Why I’m Not a Fan of Java’s Auto-Unboxing

Starting with Java 1.5, the Java compiler started automatically taking care of converting boxed versions of primitive types into primitive types where necessary, and vice-versa.  While I’m generally in favor of anything that makes programming languages easier to use, provided it doesn’t overly-complicate things, I’ve never been a huge fan of the way it was done.

Most languages either have C or C++ style primitives or object-style numbers and booleans, but Java has always had an odd mix of the two.  The easiest thing for a programmer is to simply go all the way to the object model and be done with it; my assumption is that Java didn’t do that both for the sake of continuity with C and for the sake of raw performance.

But unfortunately, the solution of auto-converting between the two worlds doesn’t really solve the problem that there are differences there that you have to be aware of.  The main difference is around null; a primitive type can’t be null, and a boxed type can, so every time you unbox an object you have to worry about how to handle null values.  If you do the unboxing by hand, at least you might have to think about it, and if you don’t at least it’ll be obvious what the error is.  But the auto-unboxing both manages to not handle null for you and manages to completely hide the errors when they do happen, which is basically a huge lose-lose in my book.  I managed to spend far too long the other day trying to figure out why the following line of code was throwing an NPE:

modifier.setEligible(!pattern.getDisplayEligibility());

My instinct is that an NPE is caused by a method call or field reference on a null object, so clearly either “modifier” or “pattern” has to be null here, right?  So after staring hard at the code for several minutes to try to figure out how that could be possible I had to go to the trouble of setting everything up in the debugger, walking through the code . . . and finding out neither was null.  Huh?  Of course, not at all obvious from reading the code is the fact that getDisplayEligibility() returns a Boolean rather than a boolean, and in this case it was returning null, meaning that the ! operator was throwing the NPE.

Normally, if you tried to apply ! to an object you’d get a compile error, but thanks to the magic of auto-unboxing Java now has all sorts of exciting ways to throw NPEs that you wouldn’t think to find.  Right after fixing that bug I ran into another, very similar error:

public boolean isScheduleRate() {
  return getPattern().getScheduleRate();
}

Again, getScheduleRate() actually returns a Boolean instead of a boolean, so if it’s null the return statement will NPE.  Combined with the way Java implemented the new for loop, that means that instead of an NPE only being possible on the . operator or [] references, you now have to look out for !, return, arithmetic operators like + and -, and for loops.

In GScript we, for better or worse, auto-coerce null to false or 0 depending on the context, which also requires you to understand that that can happen, but at least prevents the sort of hidden NPEs that the current Java approach causes.  It probably behaves like you’d expect most of the time and is generally consistent with how other languages behave.


4 Comments on “Why I’m Not a Fan of Java’s Auto-Unboxing”

  1. Carson Gross says:

    Just to justify GScript’s approach a bit more, the common case is an if statement involving a capital-B boolean from a database column somewhere:

    if( SomeBean.SomeBoolean ) {

    }

    It would really suck to have to type:

    if( SomeBean.SomeBoolean != null and SomeBean.SomeBoolean.booleanValue() ) {

    }

    everywhere. Once you accept that, the default value mapping argument pretty much follows.

    I’m unclear on why Sun decided that a NullPointerException was the correct exception to throw in this case though. Seems like something like an AutoboxFailureException would be more informative.

    Cheers,
    Carson

  2. James says:

    Alan – nice article.
    Would you be willing to repost this on JavaLobby – I think it would generate an interesting discussion there.

    If you’d like to, just send me a mail and we can organise it.
    James

  3. Doug says:

    A NullPointerException sounds like the programmer’s fault, AutoboxFailureException sounds more like Sun’s fault.
    🙂

  4. Have you ever considered writing an e-book or guest authoring on other sites?

    I have a blog based upon on the same ideas you discuss and would really like to have you share some stories/information. I know my viewers would appreciate
    your work. If you’re even remotely interested,
    feel free to send me an email.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s