Jibble News Archive
News Archive for 2005-12.
Autoboxing Considered Harmful
I was not a great fan of Java 1.5 when its new features were announced. Sure, I could see the benefits of things like autoboxing, but having taught this stuff to university students for 3 years, I couldn't help but think of the problems it could cause.
I came up with the following example, which demonstrates autoboxing in action (note: never write code like this!):
Integer a1 = 100;
Integer a2 = 100;
System.out.println(a1 == a2); // Prints "true"
Note that this code will not compile in Java 1.4 or earlier, as you cannot assign an int to an Integer without autoboxing. The equality operation could appear to return "true" because the int values inside the Integers are the same, but it's actually because when a1 and a2 are assigned, they end up pointing to the same immutable Integer object. Testing the same object for equality with itself obviously returns true.
This alone can cause some confusion, as changing the code to do things the "old" way would give different results:
Integer a1 = new Integer(100);
Integer a2 = new Integer(100);
System.out.println(a1 == a2); // Prints "false"
To most people, the above difference would be obvious - a1 and a2 both point to different Integer objects (they just happen to contain the same int value), so the equality operation returns false.
Now, let's jump back to that first example where two autoboxed Integers are compared. What happens if we change their values from 100 to 150?
Integer b1 = 150;
Integer b2 = 150;
System.out.println(b1 == b2); // Prints "false"
Most people look at this and go, "Huh? Why does it return false now?" Unfortunately, only values between -128 and +127 are assigned to the same immutable Integer object in a pool of Integers. Anything outside that range appears to be assigned to a new Integer object, so equality will never happen.
Using autoboxing in this way is a poor practice, but I can imagine it being all too easy for student programmers to fall into this trap and end up getting really confused. I even know people who work with Java every day and were very surprised by this.
Sun's advice on when to use autoboxing and unboxing is pretty sound, and should be observed and taught in order to prevent any weirdness happening:
Use them only when there is an "impedance mismatch" between reference types and primitives, for example, when you have to put numerical values into a collection. It is not appropriate to use autoboxing and unboxing for scientific computing, or other performance-sensitive numerical code. An Integer is not a substitute for an int; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.
Wise words indeed.
21 Dec 2005 - 20:59:06 GMT
Search this site
Copyright Paul Mutton 2001-2013