try {
//метод, который может выбросить IOException
throwingMethod();
} catch(IOException e) {
//явно обрабатывается
}
或使用 throws 在调用方法中显式声明:
//Так мы объявляем всему миру, что наш метод опасный
//и может выбросить исключение.
//Любой код, который вызовет метод, должен будет либо
//обработать исключение, либо передать дальше.
void myMethod() throws IOException {
throwingMethod();
}
void method(MyClass obj) {
//здесь может быть NPE
obj.method();
//и здесь может быть NPE
obj.getField().method();
//и здесь
showMessage(obj.toString());
}
显式处理NullPointerException会导致非常尴尬的代码,其中包含大量trycatch和throws。因此,对于此类异常,他们达成了妥协并声明了 class RuntimeException。
简短的回答
来设计:
抓到和
RuntimeException。长答案
@Grundy 已经解释
RuntimeException说,在规范中明确说明了这个层次结构是由 Java 作者选择的,只有他们才能可靠地解释为什么选择这个选择而不是其他选择。我将尝试解释为什么选择的层次结构是有意义的。
错误和异常
让我们从远方开始。有一个基类
Throwable。所有与抛出异常相关的方法都在其中定义。它的后代,什么Error,什么Exception,没有声明任何具体的方法。事实上,这是同一个类,但名称不同。此层次结构明确地将致命系统错误 (
Error) 与非致命异常 (Exception) 区分开来。理论上,开发人员应该只处理异常,如果发生错误,程序应该终止。例如,这个 try 块:通常会处理
NullPointerException并继续工作。但是如果它发生OutOfMemoryError了,那么执行将停止并且错误将被抛出到更高的级别。检查异常
Java 的开发人员做出了颇具 争议的决定,即代码必须显式处理可能发生的任何异常。那些。如果代码引用了可以引发异常的方法,则必须使用 try-catch 块显式处理它:
或使用 throws 在调用方法中显式声明:
如果您都不这样做,则代码将无法编译。
Error- 不检查,因为,首先,Error在大多数情况下处理没有意义,其次,错误通常与任何特定方法无关(内存溢出随时可能发生)。未经检查的异常
某些类型的异常可能非常普遍。例如,
NullPointerException它可能在调用几乎任何非静态方法时发生:显式处理
NullPointerException会导致非常尴尬的代码,其中包含大量trycatch和throws。因此,对于此类异常,他们达成了妥协并声明了 classRuntimeException。(应该从哪些异常继承的问题
RuntimeException是一个相当 有争议的问题。有人建议使用未经检查的异常来处理编程错误,但实际上选择可能很困难)RuntimeException继承自,Exception因为未经检查的异常仍然是异常,而不是错误:它可以被处理并且它始终取决于代码,而不是第三方,系统,因素。如果开发人员决定处理所有异常:,然后得到
RuntimeException。可以做得不同吗?是的,但有细微差别。考虑选项。
选项 1.检查和未检查异常的不同后代类。
可以为已检查和未检查的异常创建单独的基类:
Exception但是在这种情况下,问题就出现了:它的继任者也应该是可验证的吗?如果是,那么这个类就CheckedException失去了它的意义,我们得到了现有的层次结构。如果没有,那么它就失去了意义RuntimeException。然后我们得到第二个选项选项 2:已检查的异常继承自未检查的异常
这样的层次结构是完全可以接受的,但是 Java 设计者决定基类应该是可验证的。这符合所选择的理念:默认情况下应检查异常,仅当难以在任何地方检查时才应取消检查。不是每个人都同意这一理念,但我们拥有我们所拥有的。
结果
以下原因:
某些类的可检查性在规范中明确说明,并且与异常类的任何属性无关。继承本质上纯粹是组织/说明性的,与属性/方法继承无关。
已检查的异常是异常,而不是错误,应作为异常处理。
Java 设计者决定异常的基类应该是可检查的。
这在规范第 11.1.1 节中明确定义:
上面在规范中明确指出
checked exceptions- 这些都是 Throwable 的子类,除了RuntimeException,Error及其子类。也就是说,
RuntimeException并且Error只是编译器的特殊情况。@JonSkeet答案的翻译
RuntimeException并且Error可以不明确检查,即 它们不能被包装try-catch或方法不能throws被编译,而常规方法Exception必须由 处理try-catch或传递throws。