Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added throws clause to CS

...

In this noncompliant code example, a value of type int is converted to a value of type byte without range checking.

Code Block
bgColor#FFcccc

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
bgColor#ccccff

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
bgColor#FFcccc

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
bgColor#ccccff

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
bgColor#FFcccc

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
bgColor#ccccff

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
bgColor#ccccff

long value = /* initialize */;
int i = (int) (value % 0x100000000L); // 2^32

...

 

      03. Numeric Types and Operations (NUM)