为什么我可以在Java中抛出null?

运行时:

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

这对我来说相当惊人。 我原以为这会造成编译时错误。

为什么我可以在Java中抛出null,为什么它会将它抛出为NullPointerException?

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

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

有趣的事实 IntelliJ IDEA 12告诉我,我的line, e instanceof NullPointerException将始终是错误的。 这根本不是真的。


它看起来并不是null被视为NullPointerException ,而是试图throw null的行为本身会引发NullPointerException

换句话说, throw检查它的参数是否为空,如果为null,则抛出NullPointerException

JLS 14.18规定了这种行为:

如果对Expression的评估正常完成,生成一个空值,则会创建NullPointerException类的实例V'并抛出而不是null。 throw语句突然完成,原因是值为V'的抛出。


为什么它将它转换为NullPointerException?

根据JLS 14.18:

一个throw语句首先评估表达式。 如果表达式的评估由于某种原因突然完成,那么由于这个原因抛出突然完成。 如果Expression的求值正常完成,产生一个非空值V,那么throw语句突然完成,原因是一个带有值V的throw。 如果对Expression的求正常完成,产生一个空值,那么实例V'类NullPointerException被创建并抛出而不是null。 throw语句突然完成,原因是值为V'的抛出。

为什么我可以在Java中抛出null?

您可以抛出Throwable类型的对象,并且由于nullThrowable的有效引用,因此编译器允许它。

这就是Neal Gafter所说的

虽然null可分配给每个引用类型,但null类型本身不是引用类型。 我们的意图是,将throw语句中的表达式作为引用类型的要求将从JLS的第三版中删除,但是这种更改实际上并未将其实现为已发布的版本。 因此,这是我在SE 5中介绍的一个javac编译器错误。


它的行为符合JLS:

如果对Expression的评估正常完成,生成一个空值,则会创建NullPointerException类的实例V'并抛出而不是null。

链接地址: http://www.djcxy.com/p/13265.html

上一篇: Why can I throw null in Java?

下一篇: NullPointerException from Boolean