Auto boxing and Unboxing core concept in Java

Auto boxing in Java
Auto boxing and un-boxing is introduced in Java 1.5 to automatically convert primitive type into boxed primitive( Object or Wrapper class) in Java. If you have been using Collections like HashMap or ArrayList before Java 1.5 then you are familiar with the issue that you can not directly put primitives into Collections, instead you first need to convert them in to Object only then you can put them into Collections. Wrapper class like Integer, Double and Boolean helps for converting primitive to Object but that clutter the code. With the introduction of auto boxing and unboxing in Java this primitive to object conversion happens automatically by Java compiler which makes code more readable. But auto boxing and unboxing comes with certain caveats which needs to be understood before using them in production code and it becomes even more important because they are automatic and can create subtle bugs if you are not sure when auto boxing occurs and when auto unboxing happens. This is my fifth article on features introduced in Java 5 after my post on Java Enum,  How Generics works in Java and varargs example. In this Java tutorial we will see: What is auto boxing and unboxing?  When auto boxing and unboxing occurs in Java? and things to remember while dealing with primitives and objects in Java with code examples.


What is auto boxing and unboxing in Java
Auto Boxing and Un Boxing Example in Java 5When Java automatically converts a primitive type like int into corresponding wrapper class object e.g. Integer than its called auto boxing  because primitive is boxed into wrapper class while in opposite case is called auto unboxing, where an Integer object is converted into primitive int. All primitive types e.g. byte, short, char, int, long, float, double and boolean has corresponding wrapper class e.g. Byte, Short, Integer, Character etc and participate in boxing and unboxing. Since whole process happens automatically without writing any code for conversion its called auto boxing and auto unboxing.


When does auto boxing and unboxing occurs in Java
Auto boxing and unboxing can happen anywhere where an object is expected and primitive type is available for example In method arguments,  if you pass primitive, Java automatically converts primitive into equal value Object. Classic use of auto-boxing is adding primitive types into Collection like ArrayList in Java or creating instance of parameterized classes e.g. ThreadLocal which expect Type. here is some code example of auto boxing and unboxing in Java:

ArrayList<Integer> intList = new ArrayList<Integer>();
intList.add(1); //auto boxing
intList.add(2); //auto boxing
    
ThreadLocal<Integer> intLocal = new ThreadLocal<Integer>();
intLocal.set(4); //auto boxing

int number = intList.get(0); //auto unboxing
int local = intLocal.get(); //auto unboxing

You can find all places by applying some common sense as well, just see if an object needed or a primitive type and what is available there but don’t confuse between widening and boxing, where former refers to promoting small type into bigger type wherever expected e.g. converting byte to int. I have shared couple of conversion tutorial in java like String to int conversion and  Double to String conversion, if you like you also check those.
     

Things to remember while using auto boxing in Java
Every powerful feature comes with some caveats and corner cases, here are few which is worth remembering while using auto-boxing in Java:

1) Comparing Objects with equality Operator
I agree that auto boxing of primitive to Object  adds lot of convenience and reduce verbosity but there are few places where auto boxing is error prone e.g. equality operator "==". Since equality operator can be applied on both primitive and Objects it leads to confusion and can cause subtle issues. When you compare two object using "==" operator it compares object's identity and not value and also no auto boxing occur. By the way you its not best practice to use  equality operator to compare Objects, use equals method instead. here is an example which makes it clear :

Integer one = new Integer(1);
Integer anotherOne = new Integer(1);
    
if(one == anotherOne){
  System.out.println("both one are equal");
        
}else{
   System.out.println("Both one are not equal");
}

It will print "Both one are not equal" because of no auto boxing. Things gets more confusing when "==" comparison is combined with other logical operators like > and < which does auto unboxing before comparison. This one is explained beautifully with an example of Comparator in Effective Java, if you haven't read then go get a copy.

2) Mixing object and primitive in equality and relational operator
Another mistake to avoid while using auto-boxing and unboxing in Java is mixing  primitive and Object in equality or relational operator  much like mixing static and non static synchronized method. if we compare one primitive with another object than unboxing of object is occur which could throw NullPointerException if object is null e.g.

private static Integer count;

//NullPointerException on unboxing
if( count <= 0){
  System.out.println("Count is not started yet");
}

3) Cached Objects
One more caveat of boxing and unboxing is cached object, since valueOf() is used to create boxed primitive and it caches frequently used Object which may behave differently based upon there value as Java only cache integers from -128 to 128.  I have discussed this problem in detail on post What is wrong while using "==" with auto boxing in Java.

4) Unnecessary objects and GC overhead
Last but not least is cost associate on auto boxing and unboxing. Since auto-boxing creates unnecessary object and if that goes beyond a limit usually outside the range of cached value it can potentially slow your program by frequently causing garbage collection.

In Summary auto boxing and unboxing in Java are great convenience but demands care and awareness while using them. auto boxing and unboxing has several legitimate use case but should not be used with equality operator specially mixing with primitive and object is dangerous. If you like to read books check out Effective Java and Java 5.0 Tiger: A Developer's Notebook , those has some more insightful tips on boxing and unboxing in Java.

1 comment:

Note: Only a member of this blog may post a comment.