This post originated from an RSS feed registered with Java Buzz
by Daniel Bonniot.
Original Post: Autoboxing and NullPointerExceptions in Java 1.5
Feed Title: Daniel Bonniot's Weblog
Feed URL: http://www.jroller.com/dbr/feed/entries/rss?cat=%2FNice
Feed Description: Design ideas around the Nice programming language
How should automatic unboxing handle null values? There seems to be heavy discussion about this. Even one of the designers of this feature, Joshua Bloch, admitted having no clear idea which behaviour was the best: return the default value, or throw a NullPointerException. Initially they were planning to return the default value, but it seems they changed their minds since.
The point is that there is no good solution. In some cases, when the null value comes from the absence of assignment, it make sense to use the default value. On the other hand, in the case where null was explicitely set as the value, then null should be returned so that the client can make the difference between null and the default value, and behave appropriately.
This all boils down to the sloppy way in which Java (and many other languages) handle null. There is no way to specify whether a variable can contain the null value, or whether it can only contain a non-null instance of its declared type. I already discussed in an earlier entry how introducing this distinction can improve the specification of classes and prevent NullPointerExceptions. Now that the tricky behaviour of null backfires again, this distinction solves the confusion.
Once you can distingush between int and ?int (ony the latter allowing the null value), the unboxing question is solved. If you have a Collection<?int>, then it's clear that getting an element from it will return a ?int, so you have to properly handle the null value. On the other hand, if you have a Collection<int>, then the Nice compiler would have made sure that no null value is inserted into it, so elements can safely be unboxed to integers, with the guarantee that no NullPointerException will occur.
It's interesting to note that these "optional primitive types" (?int, ?boolean) make perfect sense. They signify: here we have this primitive value, but we might also have null. For instance, imagine a GUI asking the user a yes/no question. You don't want to give a default answer in fear that people would overlook it and leave the wrong answer, so you initially set it to "select yes or no", with a drop-down list with "yes" and "no". Then it is logical to represent this value with the type ?boolean. When validating the data, you can (and need to, as the compiler will remind you) handle the null case by kindly reminding the user to answer that question.