Autoboxing: Traps and Advantages

What is ‘autoboxing’ some people might ask?

Autoboxing is a feature, which was added in Java 5. Autoboxing is the automatic conversion of primitive data types like int, double, long, boolean to its wrapper Object Integer, Double… and vice versa. So they can be as Object e.g. in Collections.

For example:

list.add(5);

In Java 1.4 you had to write for the same result:

list.add(Integer.valueOf(5));

(The primitive types must be converted first, because a list can only contain objects.)

Advantages?

  • Less code to write.
    • The code looks cleaner.
  • The best method for conversion is automatically chosen, e.g. Integer.valueOf(int) is used instead of new Integer(int)

Disadvantages

1. Can lead to unexpected behaviour
The usage of autoboxing can lead to difficult to recognize errors. Especially if you mix wrapper with primitives in ‘equals’/’==’.

For Example this:

        Long l = 0L;
        System.out.println(l.equals(0L));
        System.out.println(l.equals(0));

Results into

true
false

2. Hiding
It hides the object creation, which can lead to a big performance loss. For example:

        Integer counter = 0;
        for(int i=0; i < 1000; i++) {
            counter++;
        }

What does ‘counter++’?
It gets the primitive int of the Integer and adds one, that it converts back to a “new” Integer (not necessarily, if the Integer cache contains this Integer).
In Java 1.4 it would look like:
Integer.valueOf(counter.intValue() + 1)

3. Overloading

 public static void main(String[] args) throws Exception
 {
 Integer l = 0;
 fubar(l);
 }
 static void fubar(long b) {
 System.out.println("1");
 }
 static void fubar(Long b) {
 System.out.println("2");
 }

The result is 1. Because there is no direct conversion from Integer to Long, so the “conversion” from Integer to long is used.

I myself stumbled across one of these errors in an simple “if”. But I don’t know anymore, how the error looked like. A other completely independent team in our company had a similar experience and they forbid to use Autoboxing in their project, too.

4. NullPointerException

You can get a NullPointerException, if the wrapper object is null and is unboxed. Pointing out the obvious there can’t be a NullPointer  with primitive variables, but they can have the value zero.

For example look at the code below. In this little example it seems obvious that there can be a NullPointerException. But let’s face it in real code these are only two lines in possible hundreds of lines of code.

HashMap<String, Integer> map = new HashMap<String, Integer>();
int x = map.get("hello");

Conclusion

IMHO “Autoboxing” is too unexpected in its behavior and can easily result in difficult to recognize errors.

Further more the performance loss on unnecessary autoboxing is too big to ignore completely. Usually I would say the performance is irrelevant, but let’s be honest we are usually dealing with a high data load in JEE, where something like this can save some per cent in processing time. Recently I took the time to make a benchmark here.
I once changed a CPU heavy logic from using Integer/Lists to int/array, which saved about 20s processing time from about 180 seconds to begin with.

I suggest to define an application wide rule how to handle autoboxing. Either disable this feature (compiler warnings help) completely or if you want to use it then handle it with care.

You can configure eclipse in the compiler options, that using autoboxing produces warnings. Java->Compiler->Errors/Warnings->”Potential programming problems”->”Boxing and unboxing conversions”

This entry was posted in common practice, Java, Performance, Uncategorized and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *