Thursday, July 15, 2010

Be aware of Autoboxing


Target audience: Beginners and Intermediates
Autoboxing is a feature added in Java 5. Boxing and unboxing give convenient ways to use Wrapper classes. The following example shows how it was used to create a Wrapper class and unwrapp it in versions previous to Java 5 and How it is used with Java 5 autoboxing

//Without autoboxing
Integer one = new Integer(1);
int intOne = one.intValue();
System.out.println("Value of one = " + intOne);

//With autoboxing
Integer intTwo = 2;
System.out.println("Value of two= " + intTwo);

I think we all know about this. But i would like to suggest to be careful when autoboxing is used. Just have a look at the bellow example.

package features;

public class AutoboxingExamples {

public static void main(String[] args) {

Integer i1 = 200;
Integer i2 = 200;
if (i1 == i2) {
System.out.println("same");
} else {
System.out.println("different");
}

Integer i3 = 10;
Integer i4 = 10;
if (i3 == i4) {
System.out.println("same");
} else {
System.out.println("different");
}
}
}

The output of this program is:

different

same

Ohh... what’s happening here??.The i1 and i2 looks fine as normal. we could also predict that two references will be different because we know JVM creates two separate instances and i1 == i2 will be return false. But what happend to i3 and i4? should not it be also ‘different’? “i3 and i4” look even same as “i1 and i2” except the value 100 and 10 respectively.

Oki, let me explain what’s happening.
When the JVM interprets the code, it interprets the Integer i3 = 10; to Integer.valueOf(10);
//Code we wrote
Integer i3 = 10;

//code JVM interprited
Integer i3 = Integer.valueOf(10);

What is happening with Integer.valueOf() is, it uses in memory cache and if the value given(eg: 10) to create the Interger object is small( between -128 and 127) then it gets the object from the cache.The cache is created while loading the IntegerCache class with it’s static block. look at the code of Integer.valueOf() method.
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}

So if int value falls between -128 and 127, the JVM gives us the same objects, that’s why we got true for i3==i4 condition.Java uses in memory cache for small integers to improve the performance.

Not only the Integer wrapper class but the following wrappers also behave the same way
Boolean
Byte
Character from \u0000 to \u007f (7f is 127 in decimal)
Short and Integer from -128 to 127

Better be careful when we have conditions with autoboxing.

1 comment:

  1. Hi,
    Autoboxing is a great feature provided by JAVA5 but using it blindly may result in very subtle problem which will take hours and hours to
    debug and find. to read more see the link
    What is the problem while using '==' in autoboxing world in Java 5 ?

    Thanks
    Javin

    ReplyDelete