当运行这个:
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,将永远是假的。这根本不是真的。
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’.”
为什么要向上转换为NullPointerException?
As for JLS 14.18:
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在java ?
可以抛出Throwable类型的对象,因为null是Throwable的有效引用,所以编译器允许这样做。
这是Neal Gafter说的(存档)
虽然null可以赋值给每个引用类型,但null类型本身并不是引用类型。我们的意图是从JLS的第三版中删除throw语句中的表达式是引用类型的要求,但这一更改实际上从未出现在发布版本中。因此,这是我在SE 5中介绍的javac编译器错误。