Why can I throw null in Java, and why does it upcast it to a NullPointerException?

Problem Statement:

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.

Solution:

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’.