当运行这个:

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);
        }
    }
}

答案是:

true  
false

这对我来说是相当惊人的。我本以为这会导致编译时错误。

为什么我可以抛出null在Java中,为什么它向上转换它到一个NullPointerException?

(实际上,我不知道它是否是一个“上置”,因为我抛出null)

除了一个非常非常愚蠢的面试问题(请不要在面试中问这个问题),我找不到任何理由抛出null。也许你想被解雇,但那…我的意思是,为什么有人会抛出null?

有趣的事实IntelliJ IDEA 12告诉我,我的行,einstanceof NullPointerException,将永远是假的。这根本不是真的。


当前回答

我不确定,但我猜“throw null”;不工作,并且尝试它会导致程序抛出一个异常,而这个异常恰好是(drum roll) NullPointerException…

其他回答

我不确定,但我猜“throw null”;不工作,并且尝试它会导致程序抛出一个异常,而这个异常恰好是(drum roll) NullPointerException…

用这种方式思考可以更明显地解释为什么这样做是有效的:

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);
}

看起来,并不是null被视为NullPointerException,而是试图抛出null的行为本身会抛出NullPointerException。

换句话说,throw检查其参数是否为非空,如果为空,则抛出NullPointerException。

JLS 14.18指定了这种行为:

如果表达式的求值正常完成,产生空值,则创建NullPointerException类的实例V',并抛出而不是null。throw语句然后突然结束,原因是一个值为V'的throw。

null可以转换为任何类型*,包括Exception。就像如果您的方法签名指定您应该返回一个Exception(或者实际上是一个字符串或Person类),您可以返回null一样,您可以抛出它。

*不包括基本类型。

它的行为符合JLS:

如果表达式的求值正常完成,产生空值,则创建NullPointerException类的实例V',并抛出而不是null。