Fundamentals 5 min read

Understanding Java Integer Caching and the Pitfalls of Using == vs equals

This article explains Java's Integer caching mechanism, why using == on wrapper objects can be misleading outside the -128 to 127 range, shows how to control the cache size with JVM options, and demonstrates bytecode inspection with javap to reveal the underlying valueOf calls.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Understanding Java Integer Caching and the Pitfalls of Using == vs equals

Alibaba's development handbook (section 4) states that all comparisons between integer wrapper objects must use equals rather than == , because values outside the -128 to 127 range are not cached and result in distinct objects.

The following code illustrates the behavior:

public class IntegerTest {
    public static void main(String[] args) {
        Integer a = 100, b = 100, c = 200, d = 200;
        System.out.println(a == b);
        System.out.println(c == d);
    }
}

Output:

true
false

Only integers within the cache range are identical with == . The source of this behavior is the Integer.valueOf method, which returns a cached instance when the value lies between IntegerCache.low and IntegerCache.high :

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

Developers can enlarge the cache by setting the JVM option -XX:AutoBoxCacheMax=<size> , which changes IntegerCache.high . After increasing the limit, the same test prints true for both comparisons.

To see how the compiler translates the code, you can use IDEA's external tool integration to run javap -c on the compiled class. Configure the tool with the JDK's javap path, arguments -c $FileNameWithoutExtension$.class , and the working directory $OutputPath$/$FileDirRelativeToSourcepath$ . The decompiled bytecode shows that each assignment to an Integer variable invokes Integer.valueOf (lines 2, 8, 15, 22).

Similar caching behavior exists for other wrapper types such as Character , Long , and Short , which you can explore by decompiling their classes in the same way.

Javaautoboxinginteger cachingequals vs ==JavapJVM options
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

login 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.