Java: Boxed values and equality
When comparing wrapper types such as Integers, Longs or Booleans using == or !=, you're comparing them as references, not as values.
If two variables point at different objects, they will not == each other, even if the objects represent the same value.
Example: Comparing different Integer objects using == and !=.
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println(i == j); // false
System.out.println(i != j); // true
The solution is to compare the values using equals()…
Example: Compare objects using .equals(…)
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println(i.equals(j)); // true
…or to unbox the operands explicitly.
Example: Force unboxing by casting:
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println((int) i == (int) j); // true
Other operators
Arithmetic (+, *, …), logical (&&, ||, …), bitwise (&, <<, …) and commparison operators other than == and != (<, <=, …) are only defined for primitive types, so when applied to boxed types the compiler will automatically unbox the operands.
Example: Operands are unboxed.
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println(i <= j); // true
Caching
To complicate matters further, autoboxing reuses cached objects for values between −128 and 127. This causes reference equality to "work" for some boxed values but not for others.
Example: 1 is within caching range, thus i and j refer to the same object:
Integer i = 1; // = Integer.valueOf(1)
Integer j = 1; // = Integer.valueOf(1) - result cached
System.out.println(i == j); // true
Example: 300 is not within caching range, thus k and l refer to different objects:
Integer k = 300; // = Integer.valueOf(300)
Integer l = 300; // = Integer.valueOf(300) - result not cached
System.out.println(k == l); // false