Why can I throw null in Java?
JavaException HandlingNullpointerexceptionJava Problem Overview
When running this:
public class WhatTheShoot {
public static void main(String args[]){
try {
throw null;
} catch (Exception e){
System.out.println(e instanceof NullPointerException);
System.out.println(e instanceof FileNotFoundException);
}
}
}
The response is:
true
false
Which was fairly stunning for me. I would have thought this would net a compile-time error.
Why can I throw null in Java, and why does it upcast it to a NullPointerException?
(Actually, I don't know if it is an "upcast", given I'm throwing null)
Aside from a really really stupid interview question (please nobody ask this in an interview) I cannot see any reason to throw null
. Maybe you want to be fired, but that's... I mean, why else would anyone throw null
?
Fun fact IntelliJ IDEA 12 tells me that my line, e instanceof NullPointerException
, will always be false. Which isn't true at all.
Java Solutions
Solution 1 - Java
It looks like it's not that null
is treated as a NullPointerException
, but that the act of attempting to throw null
itself throws a NullPointerException
.
In other words, throw
checks that its argument is nonnull, and if it is null, it throws a NullPointerException
.
JLS 14.18 specifies this behavior:
> 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'.
Solution 2 - Java
why does it upcast it to a NullPointerException?
As per JLS 14.18:
>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’.
Why can i throw null in java ?
You can throw objects of type Throwable
and since null
is a valid reference for Throwable
, compiler allows it.
This is what Neal Gafter says (archived)
Although null is assignable to every reference type, the type of null is not itself a reference type. It was our intent that the requirement that the expression in a throw statement be a reference type was to be removed from the third edition of the JLS, but that change never actually made it into the published version. Thus, this is a javac compiler bug which I introduced in SE 5.
Solution 3 - Java
It behaves in compliance with the JLS:
> 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.
Solution 4 - Java
Thinking about it this way makes it a bit more obvious as to why this works:
try {
Exception foo = null;
if(false) {
foo = new FileNotFoundException();
} // Oops, forgot to set foo for the true case..
throw foo;
} catch (Exception e){
System.out.println(e instanceof NullPointerException);
System.out.println(e instanceof FileNotFoundException);
}
Solution 5 - Java
Don't know for sure, but I'm guessing that "throw null"; does not work, and trying it causes the program to throw an exception, and that exception happens to be (drum roll) NullPointerException...
Solution 6 - Java
bharal...It looks a javac compiler bug. I think it was introduced in SE 5. Null can be assigned to any reference type. However, "the type of null" is not itself a reference type. The program compiles it because null can simply cast into Exception. And moreover throw looks for object reference after the declaration and as null can work as an object reference it displays the result.
The JLS doc about throw as :
> “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’.”
Solution 7 - Java
null can be cast to anything*, including an Exception. Just as you could return null if your method signature specifies you should return an Exception (or indeed a string, or Person class), you can throw it.
*Excluding primitive types.