Throwing null instead of an Exception in Java
11th Mar 2008As 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!
What others say
System.out.println(null instanceof Exception);
System.out.println(null instanceof Throwable); Why is it "false" for all the statements above?? Actually, alls the SOP statements above have invalid(i mean "meaningless :-)") expressions(at runtime), though they are compile time friendly ones : just because instance references can be null for some internal jvm memory management errors, and also for the sake of not breaking the rule of "instanceof" operator. Good thoughts buddy!!! Cheers Dinesh
Raghavan alias Saravanan M.
System.out.println(null instanceof Exception);
System.out.println(null instanceof Throwable); Why is it "false" for all the statements above??// That was a good insight. But here you go.. The literal "null" is getting converted of type NullPointerException at runtime when it is being thrown (used in conjunction with the 'throws' statement) - as adarsh demonstrated and with the JLS's justifications. It is NOT the same at compile time. since a literal null is not equal to anything else. Simple. that's the reason you get false for all sort of comparisons. This line proves the same System.out.println(null instanceof Object); Hope it is convincing. Cheers,
Raghavan alias Saravanan M.
public Exception getException()
{
Exception e = null;
// Do some application logic and generate the exception.
return e;
}
public void anotherMethod()
{
// This is like a factory method that generates different
// instances of Exception, conditionally
throw getException();
}

