As it's usual these days, I was spending the evening doing some extremely interesting programming in Java. It occurred to me all of a sudden, if we could compile a Java program if it threw nulls instead of exceptions!

Consider the following lines of code.

try {
    throw null;
} catch(NullPointerException e) {
    System.err.println("Caught in NullPointerException block");
} catch(Exception e) {
    System.err.println("Caught in Exception block");
} catch(Throwable t) {
    System.err.println("Caught in Throwable block");
}

Listing 1: Java code showing null being thrown.

At a first look, what do you think the result would be? Will the program compile, let alone produce an output? If it did compile somehow, to which catch block would the control be transferred? To confuse you even further, let me tell you that all of the following expressions evaluate to false!

System.out.println(null instanceof NullPointerException);
System.out.println(null instanceof Exception);
System.out.println(null instanceof Throwable);

Listing 2: Finding the type of null.

Well, here comes the big surprise! The result of execution of Listing 1 is actually, "Caught in NullPointerException block". Thus, the listing not only compiled fine, it also produced a decent output. The control got handed over to the NullPointerException catch block, somehow! It is as if the null got miraculously transformed into a NullPointerException instance. The behaviour is identical to what we would have obtained if instead of throw null;, we had throw new NullPointerException(); inside the try block.

Explanation

This is not at all an anomaly in Java given that the behaviour is neatly documented in the Java Language Specification. Here I'm quoting a few lines from ยง14.18 of the JLS, 3rd Edition.

ThrowStatement: throw Expression;

...

A throw statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the throw completes abruptly for that reason. If evaluation of the Expression completes normally, producing a non-null value V, then the throw statement completes abruptly, the reason being a throw with value V. If evaluation of the Expression completes normally, producing a null value, then an instance V' of class NullPointerException is created and thrown instead of null. The throw statement then completes abruptly, the reason being a throw with value V'.

As explained above, in our case, the expression throw null gets converted to an instance of NullPointerException before being caught by the first catch block. Quite straightforward now, isn't it?

Although such a scenario would be very rare in real life programming, it's great to see the extent of forethought the creators of Java had. Java continues to inspire me, as always!

Comments


comments powered by Disqus