Why Does Integer == Return True for Small Numbers? Uncover Java’s Integer Cache

This article explains why the == operator returns true for small Integer values in Java, detailing the internal IntegerCache mechanism, demonstrating the behavior with code examples, and showing how reflection can manipulate the cache, highlighting both the benefits and potential pitfalls of this optimization.

Programmer DD
Programmer DD
Programmer DD
Why Does Integer == Return True for Small Numbers? Uncover Java’s Integer Cache

This is an interesting discussion topic.

If you run the following code:

Integer a = 1000, b = 1000;
System.out.println(a == b); //1
Integer c = 100, d = 100;
System.out.println(c == d); //2

You will get:

false
true

Basic knowledge: == compares object references, not values. Two references to different objects are unequal even if their contents are the same.

Therefore the second statement should also be false, but it is true because Java caches small integer objects.

Inside Integer.java there is a private inner class IntegerCache that caches Integer objects from –128 to 127.

When you write Integer c = 100; the JVM actually executes Integer i = Integer.valueOf(100);. The valueOf method looks like:

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

If the value is within –128 to 127, the cached instance is returned.

Thus the following code points to the same object: Integer c = 100, d = 100; Printing c == d yields true.

The cache exists because small integers are used far more frequently than large ones, so reusing the same underlying objects reduces memory consumption.

However, the cache can be misused via reflection. The following example modifies the cache:

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Class cache = Integer.class.getDeclaredClasses()[0]; //1
    Field myCache = cache.getDeclaredField("cache"); //2
    myCache.setAccessible(true); //3
    Integer[] newCache = (Integer[]) myCache.get(cache); //4
    newCache[132] = newCache[133]; //5
    int a = 2;
    int b = a + a;
    System.out.printf("%d + %d = %d", a, a, b);
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ReflectionAutoboxingReference EqualityInteger cache
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.