Autoboxing and Null Pointer Exceptions


Updated 08/16/2006: Check out the discussion about this post on The Serverside.


I spent a while earlier today debugging a very small block of code that was throwing a NPE. There were few options for instances that could be null, but since I was looking in the wrong place for the problem, it took longer than it should have to fix.

I wrapped each method call on a potentially null object with null checks but it was still failing, and finally I realized what was going on. I was storing ints as values in a Map, e.g.

Map<Integer, Integer> cycleAreas = ...
for (Cycle cycle : cycles.values()) {
  Area area = _areaDao.create(new Area(
    analysis, tube, cycle, target,
    cycleAreas.get(cycle.getCycle()), creator));
  areas.add(area);
}

The exception occurred in the 3rd line, so either cycleAreas or cycle could be null (not really, but I added tests anyway).

Since you can’t use a primitive as a key or value in a Map, you just use autoboxing and use the associated non-primitive instead. But in this case the Map might not be fully populated, so it took a few iterations to find a case where there was no area for a given cycle.

Under the hood when you autobox and treat an Integer as an int or vice versa, the compiler inserts a call to intValue() or Integer.valueof(). Since the Integer value was null, calling intValue() blew up. For a more straightforward example, consider this code:

Integer z = 5;
Integer i = null;
int j = i;

It will fail at the last line with a NPE. It’s more obvious why if you use a decompiler on the class file:

Integer z = Integer.valueOf(5);
Integer i = null;
int j = i.intValue();

Comments are closed.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.