问题描述
对于未检查的(运行时)异常,这是可以理解的。它们实际上是通过堆栈传播的。但是为什么说检查异常不是?是的,我们必须声明(抛出)或处理(尝试捕获),但是为什么在这种情况下不称为“传播”呢?让我给你一个基本的例子:
public class Main {
void m() throws IOException {
throw new java.io.IOException("device error");//checked exception
}
void n() throws IOException {
m();
}
void p(){
try{
n();
}catch(Exception e){System.out.println("exception handled");}
}
public static void main(String args[]){
new Main().p();
}
}
我认为我只是做了一个很好的“链式”操作。那么,为什么文档说“默认情况下不传播”?
解决方法
默认情况下不传播
我相信这是here的来源。
这是不寻常的术语。 我怀疑那句话的意思是你不能只写:
void m() {
throw new IOException("device error");//checked exception
}
void n() {
m();
}
void p(){
try{
n();
}catch(Exception e){System.out.println("exception handled");}
}
因为该异常不是从m()
到n()
到p()
的“传播”,因为这是一个已检查的异常,所以该代码甚至无法编译。
如果这是未经检查的异常,它将通过此代码从m()
到n()
到p()
传播。
如果这是您想要的,则必须显式传播异常:
void m() throws IOException { ... }
void n() throws IOException { m(); }
这种传播的替代方法是在方法内部进行处理。关键是,您必须选择处理它。
,在运行时,检查和未检查异常的行为实际上根本没有区别。
检查的异常只是所有异常的子集,编译器会决定对其进行检查,并查看是否将它们明确声明为抛出或捕获。如果没有,那就是错误。
如果您能以某种方式hack the compiler to skip this check,它的行为就像运行时一样。
鉴于运行时语义是相同的,因此说一个被传播而另一个不传播是没有道理的。