class ThrowNull {
public static void main(String[] args) {
throw null;
}
}
我们知道throw的规则是throw ThrowableInstance;
,其中ThrowableInstance
必须是Throwable类型的对象或Throwable的子类。
简单类型(如int或char)以及非Throwable类(如String和Object)不能用作异常。 null
是一个特殊的Java文字,表示空值。
那么为什么throw null;
会在这段代码中编译?
答案 0 :(得分:54)
根据language specification,throw
语句定义为:
throw Expression
如果Expression
评估为null
,则会抛出NullPointerException
。具体地,
如果 Expression 的评估正常完成,产生
null
值,则会创建并抛出类NullPointerException
的实例 V'而不是null
。
由于NullPointerException
扩展RuntimeException
,因此它是未经检查的例外。这可以解释为什么没有报告此构造的编译时错误。
答案 1 :(得分:5)
编译器没有检查很多东西,它假设你做了一些它可能不知道的好理由。它试图阻止的是开发人员常犯的错误。
有可能有人认为这是
的好手throw new NullPointerException();
Integer i = null;
try {
i.intValue();
} catch (NullPointerException npe) {
System.err.println("Caught NPE");
npe.printStackTrace();
}
和
try {
throw null;
} catch (NullPointerException npe) {
System.err.println("Caught NPE");
npe.printStackTrace();
}
在Java 6 update 38中打印
Caught NPE
java.lang.NullPointerException
at Main.main(Main.java:9)
答案 2 :(得分:3)
我认为因为Null可以被转换为任何类型的引用。所以在编译时如果你抛出null而不是throwable则没有错。
答案 3 :(得分:2)
一般来说,而不只是扔。任何对象变量都可以赋值为null。所以我们可以看到抛出并不是特例。应该是吗?也许。它一致吗?是。