Fundamentals 7 min read

Understanding Java Integer Caching and Autoboxing: When == Can Mislead

This article explains Java's Integer caching mechanism, why using == to compare wrapper objects can produce unexpected results, how the IntegerCache works, how to adjust its range with JVM options, and demonstrates the behavior through code examples and javap decompilation.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Understanding Java Integer Caching and Autoboxing: When == Can Mislead

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

Consider the following code snippet:

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);
    }
}

The output is:

true
false

The reason is that the JVM caches Integer objects only for values between -128 and 127. Values outside this range are allocated on the heap, so == compares references and returns false.

The caching logic resides in Integer.valueOf(int i) :

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 upper bound with the JVM option -XX:AutoBoxCacheMax=<size> , which changes IntegerCache.high and can improve performance when frequently using large constant Integers.

To see the exact bytecode, you can use IDEA's external tool configuration to run javap -c on the compiled class. The relevant bytecode lines (2, 8, 15, 22) invoke Integer.valueOf , confirming that autoboxing always calls this method.

/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/bin/javap -c IntegerTest.class
Compiled from "IntegerTest.java"
public class com.github.codedrinker.basic.IntegerTest {
  public com.github.codedrinker.basic.IntegerTest();
    Code:
       0: aload_0
       1: invokespecial #1 // Method java/lang/Object."
":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush 100
       2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       5: astore_1
       6: bipush 100
       8: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      11: astore_2
      12: sipush 200
      15: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      18: astore_3
      19: sipush 200
      22: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      25: astore 4
      27: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
      30: aload_1
      31: aload_2
      32: if_acmpne 39
      35: iconst_1
      36: goto 40
      39: iconst_0
      40: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
      43: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
      46: aload_3
      47: aload 4
      49: if_acmpne 56
      52: iconst_1
      53: goto 57
      56: iconst_0
      57: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
      60: return
}

The same caching behavior applies to other wrapper types such as Character , Long , and Short , which also have their own cache ranges.

Understanding this mechanism helps avoid subtle bugs in Java code and can be leveraged for performance tuning.

Javaperformanceautoboxinginteger cachingequals vs ==Javap
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.