首页 文章

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

提问于
浏览
298

运行时:

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

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

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

(实际上,我没有't know if it is an 574960 , given I'米投掷null)

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

Fun fact IntelliJ IDEA 12告诉我,我的行 e instanceof NullPointerException 将永远是假的 . 这根本不是真的 .

7 回答

  • 95

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

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

    JLS 14.18 specifies这种行为:

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

  • 13

    why does it upcast it to a NullPointerException?

    根据JLS 14.18

    throw语句首先评估Expression . 如果表达式的评估由于某种原因突然完成,那么抛出就会突然完成 . 如果表达式的评估正常完成,产生非空值V,那么throw语句突然完成,原因是值为V的throw . 如果Expression的评估正常完成,产生空值,则实例V'创建并抛出NullPointerException类,而不是null . 然后throw语句突然完成,原因是值为V'的throw .

    Why can i throw null in java ?

    您可以抛出 Throwable 类型的对象,因为 nullThrowable 的有效引用,编译器允许它 .

    这就是Neal Gafter says

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

  • -3

    它的行为符合JLS

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

  • 18

    以这种方式思考它会使它更加明显地说明为什么这样做:

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

    唐't know for sure, but I'猜猜"throw null";不起作用,并尝试它会导致程序抛出异常,并且该异常恰好是(鼓滚动)NullPointerException ...

  • 21

    null可以转换为任何*,包括异常 . 就像你的方法签名指定你应该返回一个Exception(或者确实是一个字符串或Person类)一样,你可以返回null,你可以抛出它 .

    *不包括原始类型 .

  • 399

    bharal ...它看起来像一个javac编译器bug . 我认为它是在SE 5中引入的.Null可以分配给任何引用类型 . 但是,“null类型”本身不是引用类型 . 程序编译它,因为null可以简单地转换为Exception . 此外,throw会在声明后查找对象引用,并且null可以作为对象引用,它会显示结果 .

    关于throw的JLS文档:

    “throw语句首先评估表达式 . 如果表达式的评估由于某种原因突然完成,那么抛出就会突然完成 . 如果表达式的评估正常完成,产生非空值V,那么throw语句突然完成,原因是值为V的throw . 如果Expression的评估正常完成,产生空值,则实例V'创建并抛出NullPointerException类,而不是null . 然后throw语句突然完成,原因是值为V'的throw . “

相关问题