Friday, October 1, 2010

What is the problem while using "==" in autoboxing world in Java 5 ?

Some of the JVM cache objects of some wrapper class e.g. Integer from -128 to 127 and return same object which if compare via “ ==” can return true but after this range this validity doesn’t work and to make it worse this behavior is JVM dependented so better avoid this kind of check and use equals() method.

e.g.

Integer i1 = 260;
Integer i2 = 260;

if (i1 == i2)
System.out.println("i1 and i2 is equal");
else
System.out.println("i1 and i2 is not equal ");

Here you will most probably get "i1 and i2 is not equal " at least in my machine.
because in this case, unboxing operation is not involved. The literal 260 is boxed into two different Integer objects ( again it varies between JVM to JVM) , and then those objects are compared with ==. The result is false, as the two objects are different instances, with different memory addresses. Because both sides of the == expression contain objects, no unboxing occurs.


Integer i1 = 100;
Integer i2 = 100;

if (i1 == i2)
System.out.println("i1 and i2 is equal");
else
System.out.println("i1 and i2 is not equal ");


Here, most probably you will get the text "i1 and i2 is equal".
Because int values from -127 to 127 are in a range which most JVM will like to cache so the VM actually uses the same object instance (and therefore memory address) for both i1 and i2. As a result, == returns a true result.

this is very indeterministic and only shown by example since some JVM do optimization at certain integer value and try to return same object every time but its not guaranteed or written behavior.

So best is to avoid this kind of code in post java 1.5 and instead use equals() method to compare which is more deterministic.

7 comments :

Anonymous said...

In order to avoid surprise, I think it's better to always think of "==" in term of "same object" instead of "equals"

Anonymous said...

Yet another reason why I think this language is a dead end - the people responsible for the language design are simply nuts. It's rather unwise to make certain elements of the language behave differently depending on the level of optimization.

veggen said...

It doesn't really have anything to do with "recommended practice". That is the very definition of "==" and "equals".

Glamdring said...

@Anonymous (2nd) you are wrong. The practice is to never use `==` for objects. It's used only for primitives. So no confusion there.

Anonymous said...

I never use autoboxing. I use Integer.valueOf instead, so it is clear, that I am working with objects. You can configure eclipse to mark autoboxing as error.

Btw. You can configure the cache-max-value by the VM-Param -XX:AutoBoxCacheMax=X. The value 127 is default.

Javin @ FIX Protocol Tutorials said...

Hi Anonymous thanks for sharing VM-Param -XX:AutoBoxCacheMax=X to us. I think valueOf is also work on same principle and return same object until a limit most likely in the range of byte -127 to 128 and return different object outside the range.

Javin @ FIX Protocol Tutorials said...

@Glamdring , thanks for answering @Anonymous (2nd) and making it clear not to use `==` for objects.

Post a Comment