Why in Java "1000==1000" is false, and "100==100" is true ?

Why in Java "1000==1000" is false, and "100==100" is true ?

Why in Java "1000==1000" is false, and "100==100" is true ?

This is an interesting topic for discussion.

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: We know that if two references point to the same object, use == to indicate that they are equal. If two references point to different objects, use == to indicate that they are not equal, even if their contents are the same.

Therefore, the latter statement should also be false.

This is where it is interesting. If you look at the Integer.java class, you will find that there is an internal private class, IntegerCache.java, which caches all integer objects between -128 and 127.

So the thing is, all small integers are cached internally, and then when we declare something like -

Integer c = 100;

Now, if we look at the valueOf() method, we can see

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

If the value range is between -128 and 127, it returns the instance from the cache.

and so…

Integer c = 100, d = 100;

Pointed to the same object.

This is why we write

System.out.println(c == d);

We can get true.

Now you may ask, why is cache needed here?

The logical reason is that the usage rate of "small" integers in this range is higher than that of large integers. Therefore, using the same underlying objects is valuable and can reduce potential memory usage.

However, you can misuse this feature through the reflection API.

Run the following code and enjoy its charm

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

What's Your Reaction?

like
0
dislike
0
love
0
funny
0
angry
0
sad
0
wow
0