Integer Cache in Java — The -128 to 127 Gotcha
Fast recall
Quick revision
Core answer
Integer.valueOf(). Java requires boxed results for constant values from -128 through 127 to be identical, and an implementation may reuse more values. Therefore Integer a = 100; Integer b = 100; must make a == b true, but identity outside the required range must not be used as a numeric comparison.Awareness of Java's object pooling optimization and how it affects reference equality — separates candidates with real debugging experience
Expecting == to work consistently for all Integer values, not understanding why it breaks at 128
Explain the rationale behind -128 to 127 (most common int values, performance for autoboxing) and always recommend equals() for Integer comparison
Interview-ready guide
Interview answer
The Integer cache lets boxing reuse existing wrapper objects for common values. Autoboxing uses Integer.valueOf(), and Java requires boxing of constant int values from -128 through 127 to produce identical references. An implementation is allowed to reuse a wider range, so 127 is a required minimum boundary, not a safe boundary for application logic.
For example, Integer a = 100; Integer b = 100; makes a == b true because both boxing conversions use the required cached object. With Integer x = 200; Integer y = 200;, x == y is not a portable value test; it may be false and code must not depend on object reuse there. Constructing wrappers explicitly also changes identity behavior and is deprecated for Integer.
The cache affects identity only, not the stored number. I compare wrapper values with Objects.equals(a, b) when null is possible, or unbox after defining how null should be handled. That keeps the result independent of cache size and allocation choices.
Integer Cache in Java — The -128 to 127 Gotcha
Direct Answer
The Integer cache is the reuse performed by boxing through Integer.valueOf(). Java requires boxed results for constant values from -128 through 127 to be identical, and an implementation may reuse more values. Therefore Integer a = 100; Integer b = 100; must make a == b true, but identity outside the required range must not be used as a numeric comparison.
Code Example
public class IntegerCacheDemo {
public static void main(String[] args) {
Integer a = 100, b = 100;
System.out.println(a == b); // true — same cached object
System.out.println(a.equals(b)); // true — correct way
Integer x = 200, y = 200;
System.out.println(x == y); // false — different objects
System.out.println(x.equals(y)); // true — correct way
Integer edge1 = 127, edge2 = 127;
System.out.println(edge1 == edge2); // true — still cached
Integer over1 = 128, over2 = 128;
System.out.println(over1 == over2); // false — beyond the cache
}
}
Common Mistakes & Pitfalls
- Testing only with small numbers:
==comparison passes with1, 2, 5thanks to the cache, then production fails with larger IDs. - Confusion at the boundary:
Integer.valueOf(100) == Integer.valueOf(100)istruebut at200it'sfalse; this looks like broken autoboxing. - Assuming the cache is fixed: the upper bound is configurable via a JVM flag — defensive code never relies on
==. - Mixing primitives and wrappers:
Integer x = 200; int y = 200; x == yunboxes and istrue, while twoInteger200s arefalse.
Check your understanding
Answer these without looking back at the article.
- What range of values does the Integer cache cover?
- Does this caching apply to Long and Short as well?
- Will Integer i = new Integer(100) use the cache?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.