Tuesday 3 June 2014

The Advantages and Traps of Autoboxing

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:
1
list.add(5);
In Java 1.4 you had to write for the same result:
1
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:
1
2
3
Long l = 0L;
System.out.println(l.equals(0L));
System.out.println(l.equals(0));
Results into
1
2
true
false
2. Hiding
It hides the object creation, which can lead to a big performance loss. For example:
1
2
3
4
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
1
2
3
4
5
6
7
8
9
10
11
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.
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.
1
2
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. Only for the purpose of clean code this is much to ignore. I would suggest to use it are in simple JUnit tests, where you enter many hard coded numbers(You can ignore the warning with @SuppressWarnings annotation, which is one option of the eclipse hotfix). Or in simple application where you don’t handle with many data like you usually do in a JEE application.
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.
You can configure eclipse in the compiler options, that using autoboxing produces warnings.
Java->Compiler->Errors/Warnings->”Potential programming problems”->”Boxing and unboxing conversions”

No comments:

Post a Comment