...
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
|
...