当运行这个:

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,将永远是假的。这根本不是真的。


当前回答

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

*不包括基本类型。

其他回答

它的行为符合JLS:

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

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

*不包括基本类型。

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

bharal……它看起来是javac编译器错误。我认为它是在SE 5中引入的。 Null可以赋给任何引用类型。然而,“null类型”本身并不是引用类型。程序编译它,因为null可以简单地转换为Exception。 此外,throw在声明之后寻找对象引用,因为null可以作为对象引用,它显示结果。

JLS文档中关于throw的描述如下:

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

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

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

JLS 14.18指定了这种行为:

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