Java Puzzler

Yesterday I read an article of an interview with Joshua Bloch about Java. In the interview he talked about where Java was heading and some of its quirks. Here’s an example of a quirk he gave in the interview:


public class Unbelievable {
    static Integer i;
    public static void main(String[] args) {     
            if (i == 42)
                System.out.println("Unbelievable");
    }
}

Fairly innocuous bit of code … so what does it do? Well if you run it you get a NullPointerException, which is no surprise as the variable hasn’t been initialized. What is surprising is why the compiler didn’t pick this up at compile time! For example, if I modify the code to the example below, it doesn’t compile because the variable has not been initialized:


public class Unbelievable {
    public static void main(String[] args) {    
            Integer i; 
            if (i == 42)
                System.out.println("Unbelievable");
    }
}

Any Java experts out there care to explain this one to me? I compiled the above examples using Java 1.5 on the Mac.

5 thoughts on “Java Puzzler

  1. Miles Barr

    In the first example something else could have set a value to i. In fact it does get initialised, to null. All fields are initialised, objects to null, numbers to 0, booleans to false, etc.:

    http://www.artima.com/designtechniques/initiali

    Local variables aren't intialised by default.

    The current compiler does some more analysis, e.g. :

    Integer i = null;
    if (i == 42)
    System.out.println(“Unbelievable”);

    shouldn't compile either, but I think earlier Java compilers would allow it. If it does compile there could be some auto unboxing voodoo going on.

    I don't know how much program analysis the current Java compiler does, but it can always do more. Take a look at:

    http://citeseerx.ist.psu.edu/viewdoc/summary?do

    and various lint tools like:

    http://findbugs.sourceforge.net/

  2. sbuckle

    Thanks Miles. I'll take a look. Have just ordered the latest edition of Effective Java.

    I noticed that Joshua Bloch has another book called Java Puzzlers. I had a look at it and it seems to go into way more detail than I ever want to know about Java!

  3. Bob Knippen

    I'm no java expert, but I think the reason the compiler doesn't pick up an uninitialized static variable is that it could be initialized almost anywhere. That is, unlike a local (where the initialization would have to be in the same method), a static is available for anybody to initialize. When I say anybody, I mean, other methods in the class, in subclasses, or in your case (since the variable is not private) other unrelated classes. As crazy as it might seem, some other class could do: Unbelievable.i = 42; before calling the main method and the code word work just fine.

  4. Simon Buckle

    I found the answer after searching around. As Miles hinted at, there's some auto-unboxing voodoo going on! The problem, in this example, is the fact that “i” is declared as an Integer; the initial value of “i” is null. When you compare primitives and boxed primitives, the boxed primitive (“i”) is automatically unboxed. If a null object reference is auto-unboxed you get a NullPointerException. The simplest way of 'fixing' the example is to change “i” to an int. Or use a different language …

  5. Simon Buckle

    I found the answer after searching around. As Miles hinted at, there's some auto-unboxing voodoo going on! The problem, in this example, is the fact that “i” is declared as an Integer; the initial value of “i” is null. When you compare primitives and boxed primitives, the boxed primitive (“i”) is automatically unboxed. If a null object reference is auto-unboxed you get a NullPointerException. The simplest way of 'fixing' the example is to change “i” to an int. Or use a different language …

Leave a Reply