Wednesday 4 April 2012

Autoboxing and Unboxing in Java

Java 5 and above supports automatic conversion of primitive types (int, float, double etc.) to their object equivalents (Integer, Float, Double,...) in assignments and method and constructor invocations. This conversion is know as autoboxing and the reverse process is called Unboxing.

Autoboxing and Unboxing during assignments


Integer obj = 10;  // autoboxing
int i1 = obj;          // auto-unboxing

Autoboxing and Unboxing during expression evaluation


Let's take a small example of incrementing the value of Integer Object 

public class Main {

public static void main(String args[]) {

                //Before Java 5

  Integer obj = new Integer(10);
int i = obj.intValue();
i++;
obj = new Integer(i);
System.out.println("Without Autoboxing-Unboxing :" + obj);
               
               //Using Java 5

Integer obj1 = 10;
obj1++;
System.out.println("Using Autoboxing-Unboxing :" + obj1);
        
}
}

The output is 

Without Autoboxing :11
Using Autoboxing :11

Before Java 5, to increment the value of an Integer object,we have to unwrap it to primitive value, increment the primitive value, re-wrap it to Integer object again. 

In Java 5,when a boxing syntax is encoutered, the compiler generates code that would call the appropriate wrapper with its valueOf method.For Unboxing compiler generates code that would call appropriate primitiveValue() method.So when the compiler encounters the code, Integer obj1 = 10;
obj1++; , it will replace that code with the following equivalent code.


Integer obj1 = Integer.valueOf(10); --->Boxing
int i = obj1.intValue(); ----->Unboxing
i++; -----> primitive increment
obj1 = Integer.valueOf(i); ------>Boxing

Why compiler should use static valueOf() method


Since creating a new wrapper for every boxing occurance is quite expensive, they designed a pool of common wrappers.When a boxing occurs for a well-known value, instead of creating a new wrapper instance, a pre-created instance is fetched from a pool and returned. Since all wrapper instances are immutable objects, this can be done without fear of code changing the internal state of the wrapper for all of its users.They implemented this feature by introducing a new static methods called valueOf() in wrapper classes.

Please visit Wrapper Classes in Java to learn more about valueOf() method and wrapper object pooling.

It’s still not recommended to use autoboxing for scientific calculations. For example, the code d = a * b + c is using Integer classes for a, b, c and d, and the generated code is d.valueOf(a.intValue() * b.intValue() + c.intValue()). All these method invocations have their own overhead, so it’s usually recommended to use autoboxing when needed to store primitives in collections.

Autoboxing and Unboxing during Method Invocation


For example

List<Integer> list = new ArrayList<Integer>();
list.add(10);
int iPrimitive = list.get(0);

Here the add(Integer e) method of list requires an object of Integer as parameter.But we are passing primitive int value 10.The list.get(0) returns an object of type Integer but we are assigning the return value to a primitive int variable.The compiler replaces the above code with the following equivalent code.

List<Integer> list = new ArrayList<Integer>();

list.add(Integer.valueOf(10)); ----------> Autoboxing

int iPrimitive = list.get(0).intValue(); ---------> Auto-unboxing.


Pitfalls of Autoboxing and Unboxing 


Please visit  Pitfalls of Autoboxing and Unboxing to learn more about this topic.                   

No comments:

Post a Comment