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;会在这段代码中编译?
为什么会导致编译时错误?
虽然目前Java编译器本身没有将其标记为问题(除非语言规范在未来某个时间发生变化),但它显然是像"声纳"这样的静态检查器的候选者,可以根除并向开发人员指出。 也许开发人员想写"return null"......
我们知道规则是调用String a() {return null}的结果必须是(子)类或String的对象。 像Throwable或BigInteger这样的简单类不能用作字符串。 Null是一个特殊的Java文字,表示空值。 那么为什么return null没有创建任何编译时错误????? !!!! 我在这里暴露你的双重标准。 你为什么抱怨throw null而不是return null? 因此,我无法提出你的问题。 它通过双重标准过于本地化。
根据语言规范,throw语句定义为:
throw Expression
如果Expression计算为null,则抛出NullPointerException。特别,
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.
由于NullPointerException扩展RuntimeException,因此它是未经检查的异常。这可以解释为什么没有报告此构造的编译时错误。
所以null以某种方式转换为NullPointer异常,但是如果我抛出一个String或一个数字呢?我给出了运行时异常并说No exception of type String can be thrown; an exception type must be a subclass of Throwable为什么会这样?
它并不是"以某种方式转换"为NPE。语言规范说当throw获取空值时,它需要创建并抛出NullPointerException。它确实如此。规范说,throw必须给出"1)引用类型的变量或值,它可以赋值(5.2)到Throwable类型,或者2)null引用"。其他任何东西都会导致编译器错误。
还不清楚你期望语言做什么。当预期值但接收到null时,通常会抛出NullPointerException(例如,参见java.io.File的构造函数)。但是,投掷任意物体并没有明显的正确行为。 (它会生成一个异常吗?哪一个?检查或取消选中?或者你是否期望捕获一个任意对象?你会catch(String s),还是catch("oops")?)让编译器拒绝不清楚的东西往往比可能出人意料的要好运行时的行为。
编译器没有检查很多东西,它假设你做了一些它可能不知道的好理由。它试图阻止的是开发人员常犯的错误。
有人可能认为这是一个很好的简写
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更新38打印
Caught NPE
java.lang.NullPointerException
at Main.main(Main.java:9)
@DanielWerner所有异常和错误,甚至可以捕获OutOfmemoryError和ThreadDeath。 ;)看看我的例子。
我认为因为Null可以被转换为任何类型的引用。所以在编译时它没有错,如果你抛出null而不是throwable。
究竟。返回String的方法可能返回null。为什么字符串变量可以为null但是Throwable变量不能? OP肯定是短视(x)或练习双重标准。
听起来不错,但事实并非如此。看到接受的答案。
在generel,而不仅仅是扔。任何对象变量都可以赋值为null。所以我们可以看到抛出并不是特例。应该是吗?也许。它一致吗?是。
java中任何变量都可以被赋值为null 关于异常处理:为什么“throw null”没有在Java中创建编译错误?...