阅读本书中的异常时,我发现了以下语句:
编译器在编译时检查已检查的异常。
和
编译器不会在编译时检查未经检查的异常。
因此,如果我们也可以这样说,IOException
或者 SQLException
位于 Checked Exceptions 类树之下。java 编译器如何知道会有一个异常,而IllegalArgumentException
我的理解可能 不会保留在代码中。
此外,必须捕获已检查异常而不是未检查异常这一事实到底意味着什么?
已检查的异常要求您throws
向方法签名添加声明,或者try
catch
在其周围添加一个块。
public void checked() throws IOException {
throw new IOException(); // compiles just fine
}
public void checked() {
try {
throw new IOException();
} catch (IOException e) {
// ...
}
}
这将不起作用:
public void checkedWithoutThrows() {
throw new IOException(); // will not compile
}
未经检查的异常不需要这个。
public void unchecked() {
throw new RuntimeException();
}
而且,为了完整起见,从已检查的异常中确定未检查的方法是未检查的异常都从RuntimeException
某个点或另一个点下降。
java中的异常都以相同的方式工作。
检查和未检查异常(它们都是RuntimeException的子类)之间的区别,如果对于引发检查异常的方法,调用该方法的人必须尝试/捕获异常,或者将他自己的方法声明为抛出该异常。
所以如果我有一个方法:
void throwsACheckedException() throws SomeCheckedException;
无论谁调用它,都必须做两件事之一。任何一个:
try {
throwsACheckedException();
} catch (SomeCheckedException e) {
//do something
}
或者
void someCallingMethod() throws SomeCheckedException { //pass it on
throwsACheckedException();
}
未经检查的异常您不必声明,调用该方法的人也不必显式捕获。例如:
void someInnocentLookingMethod() {
throw new NullPointerException("surprise!"); //...extends RuntimeException
}
然后您可以简单地调用它,而无需尝试/捕获麻烦:
void unsuspectingVictim() {
someInnocentLookingMethod();
}
未经检查的异常通常用于可能随时出现在您身上的事情,因此强迫开发人员尝试/捕捉它们会使代码非常乏味(例如 NullPointerException),尽管有些人认为检查的异常完全是邪恶的: -)
对于 Checked 异常,您会在编译时看到错误并说您必须处理它们。运行时异常不会在您的代码中提供任何需要处理的错误或警告。
编译器期望异常(Checked exceptions)并要求您处理它。