Integer Cache in Java

Naveen AnamaneniUpdated · 4 min read

Here's a famous Java puzzle: two Integer variables holding 127 are ==, but two holding 128 are not. Nothing is wrong with the numbers. == on objects compares references, and Java keeps a ready-made cache of Integer objects for small values. Inside the cache range, boxing the same value always returns the same object; outside it, every boxing creates a new one.

The Puzzle

Cache.java▶ Try it
public class Cache {
    public static void main(String[] args) {
        Integer a = 127, b = 127;
        Integer c = 128, d = 128;
        System.out.println(a == b);
        System.out.println(c == d);
        System.out.println(c.equals(d));
        System.out.println(c.intValue() == d.intValue());
 
        Long x = 127L, y = 127L;
        Double p = 1.0, q = 1.0;
        System.out.println(x == y);
        System.out.println(p == q);
    }
}
Output
true
false
true
true
true
false

How it works

  1. Integer a = 127 compiles to Integer.valueOf(127). For values from -128 to 127, valueOf returns an object from a cache built when Integer loads, so a and b refer to the same object: true.
  2. 128 is outside the cache, so each valueOf(128) creates a new object: c == d is false.
  3. equals compares values: true. Comparing unboxed ints also works.
  4. Long has the same -128 to 127 cache. Double has no cache, so even 1.0 == 1.0 on Double objects is false.

Inside the Cache

Inside the range: one shared object. Outside: a new object each time

Integer.valueOf looks like this (simplified from the JDK source):

java.lang.Integer (simplified)
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high) {
        return IntegerCache.cache[i + (-IntegerCache.low)];
    }
    return new Integer(i);
}

The cache is safe to share because Integer objects are immutable. It saves memory and time for the small numbers programs use most.

WrapperCached values
Integer-128 to 127 (the upper limit can be raised)
Long, Short, Byte-128 to 127
Character0 to 127
BooleanBoth values: TRUE and FALSE
Float, DoubleNone

The upper limit for Integer can be raised with a JVM option, for example java -XX:AutoBoxCacheMax=1000 Cache; then c == d above prints true. That's a curiosity, not a fix: code must never depend on it.

Why This Matters in Real Code

The bug usually hides in tests: ids, quantities and counts in test data are small, so == passes; in production, with values like 4500, it fails.

A real-looking bug
Integer expected = order.getQuantity();
Integer actual = shipment.getQuantity();
if (expected == actual) {           // true for 50, false for 500
    markComplete();
}

Common Mistakes

Using == on Integer, Long or other wrappers. Use equals or Objects.equals.

Trusting tests that use small numbers. The cache hides the bug until values exceed 127.

Writing new Integer(5). The constructor is deprecated for removal; use Integer.valueOf(5) or autoboxing.

Interview Corner

Why does Integer a = 127, b = 127; a == b return true, but 128 returns false?

Autoboxing calls Integer.valueOf, which returns cached objects for values from -128 to 127. Two boxings of 127 return the same cached object, so ==, which compares references, is true. 128 is outside the cache, so each boxing creates a new object and == is false. Values should be compared with equals.

Which wrapper classes have caches?

Integer, Long, Short and Byte cache -128 to 127; Character caches 0 to 127; Boolean has its two constants. Float and Double have no cache. Only Integer's upper limit is configurable, with -XX:AutoBoxCacheMax.

Practice

  1. Easy: Predict, then check: Integer.valueOf(100) == Integer.valueOf(100) and Integer.valueOf(1000) == Integer.valueOf(1000).
  2. Harder: Write a loop from 120 to 135 that boxes i twice and prints where == stops being true.

Quick check: Integer cache

4 questions
1Integer a = 100, b = 100; a == b is:
2Integer c = 200, d = 200; c == d is:
3What's the default Integer cache range?
4How should two Integer values be compared?

Key Takeaways

Was this tutorial helpful?

Lesson 161 of 482