Why can I throw null in Java? [duplicate]

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.


Solution 1:

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:

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:

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.