Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The values of boxed primitives cannot be directly compared using the == and != operators because they compare object references, not object values. Programmers might find this behavior surprising because autoboxing memoizes (or caches) the values of some primitive variables. Consequently, reference comparisons and value comparisons produce identical results for the subset of values that are memoized.

...

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

Primitive Type

Boxed Type

Fully Memoized

boolean, byte

Boolean, Byte

yes

char, short, int

Char, Short, Int

no

The == and != operators may be used to compare the values of fully memoized types.

The == and != operators must not may only be used for comparing the values of boxed primitives outside these specific casesthat are not fully memoized, when the range of values represented is guaranteed to be within the ranges specified by the JLS to be fully memoized.

In general, avoid using these operators to compare the values of boxed primitives that are not fully memoized.

Implementations are allowed, but not required, to memoizize values memoize additional values:

Less memory-limited implementations might, for example, cache all characters and shorts, as well as integers and longs in the range of -32K - +32K.

Code that depends on implementation-defined behavior is not portable.

Noncompliant Code Example

...

Code Block
bgColor#CCCCFF
public class Wrapper {
 public static void main(String[] args) {
   // Create an array list of integers, where each element
   // is greater than 127
   ArrayList<Integer> list1 = new ArrayList<Integer>();

   for (int i = 0; i < 10; i++) {
     list1.add(i + 1000);
   }

   // Create another array list of integers, where each element
   // has the same value as the first one
   ArrayList<Integer> list2 = new ArrayList<Integer>();
   for (int i = 0; i < 10; i++) {
     list2.add(i + 1000);
   }
 
   // Count matching values
   int counter = 0;
   for(int i = 0; i < 10; i++) {
     if (list1.get(i).equals(list2.get(i))) {  // uses 'equals()'
       counter++;
     }
   }
 
   // print the counter: 10 in this example
   System.out.println(counter);
 }
}

Exceptions

Noncompliant Code Example (new Boolean)

Constructors for class Boolean return distinct newly-instantiated objects. Using the reference equality operators in place of value comparisons will yield unexpected results.EXP03-EX1: The values of autoboxed Boolean variables may be compared using the reference equality operators because the Java language guarantees that the autoboxing yields either Boolean.True or Boolean.False (as appropriate). These objects are guaranteed to be singletons.

Code Block
bgColor#CCCCFF#FFCCCC
Boolean b1 = new Boolean("true; // Or Boolean.True");
Boolean b2 = new Boolean("true; // Or Boolean.True");
b1 == b2;          // alwaysnever equal

Compliant Solution (new Boolean)

The values of autoboxed Boolean variables may be compared using the reference equality operators because the Java language guarantees that the Boolean type is fully memoized. Consequently, these objects are guaranteed to be singletonsNote, however, that the constructors for class Boolean return distinct newly-instantiated objects. Using the reference equality operators in place of value comparisons will yield unexpected results in this case.

Code Block
bgColor#FFCCCC#CCCCFF
Boolean b1 = new Boolean("true");true; // Or Boolean.True
Boolean b2 = new Boolean("true"); true; // Or Boolean.True
b1 == b2;          // neveralways equal

Exceptions

EXP03-EX1 In the unusual case where a program is guaranteed to execute only on a single implementation, it is permissible to depend upon implementation-specific ranges of memoized vulnerabilities.

Risk Assessment

Using the equivalence operators to compare values of boxed primitives can lead to erroneous comparisons.

...