运行时:
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 回答
看起来并不是
null
被视为NullPointerException
,而是试图throw null
本身的行为抛出NullPointerException
.换句话说,
throw
检查其参数是否为非空,如果为null,则抛出NullPointerException
.JLS 14.18 specifies这种行为:
why does it upcast it to a NullPointerException?
根据JLS 14.18:
Why can i throw null in java ?
您可以抛出
Throwable
类型的对象,因为null
是Throwable
的有效引用,编译器允许它 .这就是Neal Gafter says
尽管null可分配给每个引用类型,但null的类型本身不是引用类型 . 我们的意图是要求将throw语句中的表达式作为引用类型从JLS的第三版中删除,但该更改实际上从未实际进入已发布的版本 . 因此,这是我在SE 5中介绍的javac编译器错误 .
它的行为符合JLS:
以这种方式思考它会使它更加明显地说明为什么这样做:
唐't know for sure, but I'猜猜"throw null";不起作用,并尝试它会导致程序抛出异常,并且该异常恰好是(鼓滚动)NullPointerException ...
null可以转换为任何*,包括异常 . 就像你的方法签名指定你应该返回一个Exception(或者确实是一个字符串或Person类)一样,你可以返回null,你可以抛出它 .
*不包括原始类型 .
bharal ...它看起来像一个javac编译器bug . 我认为它是在SE 5中引入的.Null可以分配给任何引用类型 . 但是,“null类型”本身不是引用类型 . 程序编译它,因为null可以简单地转换为Exception . 此外,throw会在声明后查找对象引用,并且null可以作为对象引用,它会显示结果 .
关于throw的JLS文档: