...
In this noncompliant code example, a value of type int
is converted to a value of type byte
without range checking.
Code Block | ||
---|---|---|
| ||
class CastAway {
public static void main(String[] args) {
int i = 128;
workWith(i);
}
public static void workWith(int i) {
byte b = (byte) i; // b has value -128
// work with b
}
}
|
...
This compliant solution validates that the value stored in the wider integer type is within the range of the narrower type before converting to the narrower type.
Code Block | ||
---|---|---|
| ||
class CastAway { public static void workWith(int i) throws ArithmeticException { // check if i is within byte range if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE)) { throw new ArithmeticException("Value is out of range"); } byte b = (byte) i; // work with b } } |
...
The narrowing primitive conversions in this noncompliant code example suffer from loss in the magnitude of the numeric value as well as a loss of precision.
Code Block | ||
---|---|---|
| ||
float i = Float.MIN_VALUE;
float j = Float.MAX_VALUE;
short b = (short) i;
short c = (short) j;
|
...
This compliant solution range-checks both the i
and j
variables before converting to the resulting integer type. Because both values are out of the valid range for a short
, this code will always throw an ArithmeticException
.
Code Block | ||
---|---|---|
| ||
float i = Float.MIN_VALUE;
float j = Float.MAX_VALUE;
if ((i < Short.MIN_VALUE) || (i > Short.MAX_VALUE) ||
(j < Short.MIN_VALUE) || (j > Short.MAX_VALUE)) {
throw new ArithmeticException ("Value is out of range");
}
short b = (short) i;
short c = (short) j;
// other operations
|
...
The narrowing primitive conversions in this noncompliant code example suffer from a loss in the magnitude of the numeric value as well as a loss of precision. Because Double.MAX_VALUE
is larger than Float.MAX_VALUE
, c
receives the value infinity
and because Double.MIN_VALUE
is smaller than Float.MIN_VALUE
, b
receives the value 0
.
Code Block | ||
---|---|---|
| ||
double i = Double.MIN_VALUE;
double j = Double.MAX_VALUE;
float b = (float) i;
float c = (float) j;
|
...
This compliant solution performs range checks on both i
and j
before proceeding with the conversions. Because both values are out of the valid range for a float
, this code will always throw an ArithmeticException
.
Code Block | ||
---|---|---|
| ||
double i = Double.MIN_VALUE;
double j = Double.MAX_VALUE;
if ((i < Float.MIN_VALUE) || (i > Float.MAX_VALUE) ||
(j < Float.MIN_VALUE) || (j > Float.MAX_VALUE)) {
throw new ArithmeticException ("Value is out of range");
}
float b = (float) i;
float c = (float) j;
// other operations
|
...
This exception does not permit narrowing conversions without range-checking among integral types. The following code example demonstrates how to perform explicit narrowing from a long
to an int
where range-checking is not required.
Code Block | ||
---|---|---|
| ||
long value = /* initialize */;
int i = (int) (value % 0x100000000L); // 2^32
|
...