Fundamentals 4 min read

Understanding Java Integer Caching and the == Operator

This article explains how Java caches Integer objects in the range -128 to 127, why the == operator behaves differently for small and large integers, and demonstrates how to inspect and manipulate the cache using reflection.

Architecture Digest
Architecture Digest
Architecture Digest
Understanding Java Integer Caching and the == Operator

This is an interesting discussion topic.

If you run the following code:

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

You will get: false<br/>true Basic knowledge: if two references point to the same object, the == operator reports true; if they point to different objects, == reports false even when the contents are equal.

Therefore, the later statement should also be false.

The interesting part is that the Integer class contains a private inner class IntegerCache that caches all Integer objects between -128 and 127.

Thus, all small integers are cached internally, and when we declare something like: Integer c = 100; Java actually executes: Integer i = Integer.valueOf(100); Looking at the valueOf() method, we see:

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

If the value is within -128 to 127, the method returns the cached instance.

So: Integer c = 100, d = 100; Both variables point to the same object.

This is why the statement System.out.println(c == d); produces true.

You might wonder why this caching is needed.

The logical reason is that small integers are used far more frequently than large ones, so sharing the same underlying object reduces memory consumption.

However, the cache can be misused via the reflection API.

Run the following code to see the effect:

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

If this article helped you, please don’t be stingy with your likes, thank you!

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.

JavaMemory OptimizationvalueOfinteger cachingReference Equality
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

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.