下面的内容如何正确?我希望编译器告诉我使用throws Exception
或throws RuntimeException
public void method1() throws NullPointerException {
throw new RuntimeException();
}
为什么我认为它不正确 - > Bcoz NPE是RTE,但RTE不是NPE
这是怎么回事?我希望编译器告诉我使用throws Exception
或throws RuntimeException
或throws NumberFormatException
public void method2() throws NullPointerException {
throw new NumberFormatException();
}
public void method3() throws Exception { // this is fine, as expected
throw new RuntimeException();
}
public void method4() throws RuntimeException { // this is fine, as expected
throw new NullPointerException();
}
public void method5() throws Exception { // this is fine, as expected
throw new NullPointerException();
}
答案:
对于RTE,即使你没有为方法添加throws
子句,编译器也不会说什么
public void method6() { // no compile time errors!!
throw new NullPointerException();
}
但是当我们明确地说'throw new NullPointerException();
'时,为什么编译器会忽略它?
它与“throw new SQLException()
;”相同
在运行时没有抛出一些对象被评估为null,并在该null对象上调用了一个动作。
通常,函数必须声明它可以抛出的所有异常,但是RTE正在绕过它!
RTE是未经检查的例外情况。但是当你说抛出新的RTE时,仍然没有检查?!
问题 - 这不是一个缺陷吗?或者请纠正我理解为什么会这样
请注意,此问题不是已检查异常与未经检查的异常之间的区别。 问题不在于任何类型的异常或错误之间的区别。
问题是为什么没有处理显式标记的RunTimeException,或者没有强制编译器处理它。
例如:
public void methodA() { // methodA is not forced to handle the exception.
methodB();
}
public void methodB() throws RuntimeException {
}
答案 0 :(得分:5)
你误解了。
已检查的异常是在编译时检查的异常(因此它们的名称)。因此,如果您有抛出异常doFoo
的方法BarException
,则必须声明该方法抛出BarException:
void doFoo() throws BarException { }
未经检查的异常是编译器未检查的异常,因此您不必声明抛出它们
假设throw new Exception()
仅抛出已检查异常的新实例,或者在RuntimeException的情况下未选中。仅在您使用throw
子句实际抛出已检查异常时检查因子的情况。
至于它是否是一个缺陷,现在这是一个备受诟病的主题。使用抛出大量未经检查的异常的API而不记录它们抛出这些异常往往会令人讨厌。但是,有时可能会出现基于应用程序的唯一运行时状态而发生的异常,您无法声明可能会抛出某个已检查的异常,这就是运行时异常闪耀的地方(如NullPointerException
)
答案 1 :(得分:1)
我想我理解这个问题,你想知道它是否是一个设计缺陷,你在方法的抛出条款中包含的任何异常都不会被计算为已检查。
检查异常的核心前提是我们可以在抛出异常的站点告诉是否有人想要处理此异常。如果NullPointerException在某些情况下被视为已检查但在其他情况下未被考虑,则没有任何考虑因素,其想法是它始终是一件事或另一件事。同样,为了最初包括这一点,在紧迫的截止日期之前编写更多的代码,之后对此进行更改将意味着破坏现有的用户代码。这就是为什么Java没有这个功能的原因。