提问人:bharal 提问时间:7/11/2013 最后编辑:Peter Mortensenbharal 更新时间:6/8/2020 访问量:36656
为什么我可以在 Java 中抛出 null?[复制]
Why can I throw null in Java? [duplicate]
问:
运行此命令时:
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?
(实际上,我不知道这是否是“上投”,因为我抛出的是空)
除了一个非常非常愚蠢的面试问题(请不要在面试中问这个问题)之外,我看不出有任何理由.也许你想被解雇,但那是......我的意思是,为什么还有人会?throw null
throw null
有趣的事实 IntelliJ IDEA 12 告诉我,我的行 , 将永远是假的。这根本不是真的。e instanceof NullPointerException
答:
看起来它不是被视为 ,而是试图自己抛出 .null
NullPointerException
throw null
NullPointerException
换句话说,检查其参数是否为非空,如果为空,则抛出 .throw
NullPointerException
JLS 14.18 指定了以下行为:
如果表达式的计算正常完成,生成 null 值,则创建并抛出类 NullPointerException 的实例 V',而不是 null。然后 throw 语句突然完成,原因是值为 V' 的抛出。
评论
throw null
throw null
null
Exception generateExceptionForErrorCode( int errorCode )
null
throw null
throw new NullPointerException()
throw new SomethingException()
throw existingExceptionYouGotFromSomewhere
null
不确定,但我猜是“抛出 null”;不起作用,尝试它会导致程序抛出异常,而该异常恰好是(鼓声)NullPointerException...
它的行为符合 JLS:
如果表达式的计算正常完成,生成 null 值,则创建并抛出类 NullPointerException 的实例 V',而不是 null。
为什么它会将其转换为 NullPointerException?
根据 JLS 14.18:
throw 语句首先计算 Expression。如果表达式的计算由于某种原因突然完成,则抛出会因此而突然完成。如果表达式的计算正常完成,生成非空值 V,则 throw 语句突然完成,原因是抛出值为 V 的抛出。 如果表达式的计算正常完成,生成 null 值,则创建并抛出类 NullPointerException 的实例 V',而不是 null。然后 throw 语句突然完成,原因是值为 V' 的抛出。
为什么我可以在java中抛出null?
您可以抛出 and 类型的对象,因为是 的有效引用,编译器允许它。Throwable
null
Throwable
尽管 null 可以分配给每个引用类型,但 null 的类型本身并不是引用类型。我们的意图是从 JLS 的第三版中删除抛出语句中的表达式是引用类型的要求,但该更改实际上从未进入已发布的版本。因此,这是我在 SE 5 中引入的 javac 编译器错误。
评论
throw
null
javac
javac
以这种方式思考可以更清楚地了解为什么会这样:
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);
}
巴拉尔...它看起来像一个 javac 编译器错误。我认为它是在 SE 5 中引入的。 可以将 Null 分配给任何引用类型。但是,“null 的类型”本身并不是引用类型。程序编译它,因为 null 可以简单地转换为 Exception。 此外,throw 在声明后查找对象引用,并且由于 null 可以用作对象引用,因此它显示结果。
JLS 文档中关于抛出的内容是:
“throw 语句首先计算表达式。如果评估 的表达式由于某种原因突然完成,然后抛出 由于这个原因突然完成。如果对表达式的计算 正常完成,产生非空值 V,然后抛出 语句突然完成,原因是抛出值为 V。 如果表达式的计算正常完成,则生成 null 值,则创建类 NullPointerException 的实例 V' 并抛出而不是 null。然后,throw 语句完成 突然,原因是值为 V' 的投掷。
评论
null 可以强制转换为任何内容*,包括 Exception。就像如果方法签名指定应返回 Exception(或者实际上是字符串或 Person 类)可以返回 null 一样,也可以抛出它。
*不包括基元类型。
评论
NullPointerException
FileNotFoundException
评论
会抛出 null
”——人们可能会无意中这样做(比如在 where returns 中)。回复“有趣的事实”——我猜 IntelliJ 不是那么聪明。提交错误报告!e
null
e instanceof XYZ
false
XYZ
null
NullPointerException
throw this.lastException();
lastException()
null
e instanceof NullPointerException
将始终为 false。这根本不是真的“——双关语?objects
Throwable
Throwable
null