DEV Community

Md Marzukul Islam
Md Marzukul Islam

Posted on

Understanding Integer Caching in Java, The Hidden Optimization You Might’ve Missed

Ever wondered why sometimes two seemingly identical Integer objects in Java are actually the same object in memory, and sometimes they aren’t?

Welcome to the fascinating world of Integer Caching, a small but clever optimization built right into the Java Virtual Machine (JVM) that quietly boosts performance and saves memory.

What Is Integer Caching?

In Java, objects like Integer, Long, Byte, and Character are immutable wrapper classes around primitive types. Whenever you use autoboxing, such as:

    Integer a = 100;  // autoboxing of int to Integer
Enter fullscreen mode Exit fullscreen mode

the JVM doesn’t always create a new Integer object. Instead, it might reuse an existing one, thanks to Integer caching.

How It Works

By default, Java maintains a cache of Integer objects for values between -128 and +127.

So when you write:

    Integer x = 100;
    Integer y = 100;
    System.out.println(x == y);  // true
Enter fullscreen mode Exit fullscreen mode

Both x and y refer to the same cached object from the JVM’s internal pool.

However, when you go beyond this range:

    Integer p = 128;
    Integer q = 128;
    System.out.println(p == q);  // false
Enter fullscreen mode Exit fullscreen mode

Each value gets a new Integer object, since 128 is outside the default cache range.

Why -128 to 127?

This range was chosen because:

  • These values are commonly used (especially in loops, small counters, array indexes, etc.).
  • -128 to 127 fits neatly within a single byte (Byte range).

This small range gives a big payoff, fewer object allocations and faster comparisons for the most frequently used numbers.

JVM Customization For Caching Range

The upper limit of the cache can actually be customized!

You can modify it using the JVM option:

    -Djava.lang.Integer.IntegerCache.high=<value>
Enter fullscreen mode Exit fullscreen mode

For example, if your application heavily uses numbers up to 1000, you could extend the cache like this:

    -Djava.lang.Integer.IntegerCache.high=1000
Enter fullscreen mode Exit fullscreen mode

A Common Pitfall

It’s important to remember that == compares object references, not values.

That’s why you might see confusing results:

    Integer a = 100;
    Integer b = 100;
    System.out.println(a == b); // true (cached)

    Integer c = 128;
    Integer d = 128;
    System.out.println(c == d); // false (not cached)
Enter fullscreen mode Exit fullscreen mode

When comparing numeric values, always use .equals() instead:

    System.out.println(c.equals(d)); // true
Enter fullscreen mode Exit fullscreen mode

Top comments (0)