Weird Autoboxing In Java

Abhimanyu
2 min readOct 26, 2019

The Problem.

What is the problem in the above program?

In the above problem first statement prints true, whereas the second print statement prints false.

When a1,a2 contain same value and b1,b2 contain same value, then why only a1==a2 is true but b1==b2 is false;

Let’s understand why java shows this weird behaviour. First, let us understand what is autoboxing.

The Autoboxing

Whenever we assign a primitive int value to an Integer reference type, like b1=1000: java creates*(or returns from cache) an Integer object with value 1000 and assigns it to the reference variable (b1).

This automatic conversion of primitive int to Integer object is called autoboxing in java.

The reason a1==a2 returns true and b1==b2 returns false is that, java caches cache Integer objects in range [-128,127] inclusive.

So whenever we create an integer object with value in the range [-128,127] java returns the object instance from the cache. Because of this a1 and a2 point to same Integer object with value 100 in the cache, hence a1==a2 returns true. But for b1 and b2 new objects are created hence b1 and b2 both point to different objects, hence b1==b2 returns false.

Caching is applied only when we get the Integer object with either Integer.parseInt(i) method or Integer.valueOf(i) methods. (valueOf(i) method calls parseInt(i) method internally).

If we create two Integer objects with the same value explicitly (using new operator), then no cached objects are returned and new objects are created for each int value.

Refer the program below

In this above example both print statements print false, unlike the previous example.

To avoid this problem we should always compare the integer objects using equals method instead of == operator. (equals method in Integer class is overloaded and compares two objects by value.)

Why java does this optimization?

This is done to save memory and optimizing code at the same time. Caching these objects allows better programs optimization due to better cache efficiency as it is not required to create an Integer object of each int literal and can be returned directly from the cache. (an Integer object takes up something like 12 bytes)

Now, why only catching integers in range -128 to 127?

This default cache range might be JVM implementation-dependent and may vary.

This is also based on the assumption that theses small integers will occur more often than other integers, that's why it make sense to avoid the overhead of creating an Integer object for same ints values repeatedly.

Integer Caching in java

When JVM initialises, an Integer cache is created for the int values in the range -128 to 127. The size of the cache can be controlled with flag.

-XX:AutoBoxCacheMax=<size>

Caching is applied only when we get the Integer object with either Integer.parseInt(i) method or Integer.valueOf(i) methods, not applicable when we create a new object with new operator (new Integer());

below is the snippet from open-JDK Integer class implementation to show this cache.

Refer this link to see Integer class implementation.

Integer class open JDK implementation

--

--