Integer caching — predict the three == comparisons
Given autoboxing and the Integer cache, decide the result of each comparison and explain why two equal-looking values can compare differently.
Constraints:
- reason about reference identity (
==), notequals - account for the default
Integercache range
Integer a = 100, b = 100; // r1 = a == b ?
Integer c = 200, d = 200; // r2 = c == d ?
Integer e = new Integer(100), f = new Integer(100); // r3 = e == f ?
Determine r1, r2, r3 and justify each.
r1 is true, r2 is false, r3 is false. Autoboxing calls Integer.valueOf, which caches instances for -128..127, so 100 returns the same cached object (== true), but 200 is outside the range and boxes a fresh object each time (== false). new Integer(100) always allocates, so two new calls are never ==.
- ✗Assuming
==on boxedIntegeralways compares numeric value rather than reference identity - ✗Believing the cache covers all values, not just
-128..127 - ✗Thinking
new Integer(100)participates in caching instead of always allocating
- →How can you change the upper bound of the
Integercache? - →Why was the
new Integer(int)constructor deprecated in Java 9?
Walkthrough
Integer a = 100, b = 100;
System.out.println(a == b); // true — both from the cache
Integer c = 200, d = 200;
System.out.println(c == d); // false — outside the cache, two objects
Integer e = new Integer(100), f = new Integer(100);
System.out.println(e == f); // false — new always allocates
Autoboxing the literal Integer a = 100; compiles to Integer.valueOf(100). valueOf keeps a cache of objects for -128..127 and returns a ready instance from it. So a and b reference one object → == is true.
200 is outside the cache, so valueOf builds a new object each time → c == d is false.
new Integer(100) bypasses valueOf and always allocates, so e == f is always false.
The upper bound is configurable with -XX:AutoBoxCacheMax=<n> (or -Djava.lang.Integer.IntegerCache.high=<n>). Compare wrapper values with equals, never ==.