什么是异常传播?
我在谷歌尝试但对结果不满意。如果可能的话,还请举一些例子来解释。 C ++,php和java语言更可取。
答案 0 :(得分:15)
令人惊讶的是,在Java tutorial page about exceptions中解释了它。
异常从一个方法传播到另一个方法,直到它被捕获为止。因此,如果a()
调用b()
,调用c()
,调用d()
,如果d()
抛出异常,则异常将从d传播到c b到a,除非其中一种方法捕获异常。
答案 1 :(得分:11)
简答:未捕获的异常会在调用堆栈中传播,直到堆栈变空,此传播称为异常传播。
答案很长: 在方法抛出异常之后,运行时系统在调用堆栈中搜索包含可以处理异常的代码块(异常处理程序)的方法。搜索从发生错误的方法开始,并按照调用方法的相反顺序继续通过调用堆栈。找到适当的处理程序后,运行时系统会将异常传递给处理程序。此外,还有值得注意的一点:
让我们说,我们有一系列方法,其中method3()调用method2(),method2()调用method1()。所以当
1)方法3()和方法3()中发生异常,我们没有任何异常处理程序。
2)未捕获的异常将在堆栈中向下传播,即它将检查method2()中的相应异常处理程序。
3)再次在method2中,如果我们没有任何异常处理程序,那么再次异常会向下传播到method1(),在那里它会找到异常处理程序。
示例:强>
class ExceptionPropagation{
void method3(){
int result = 100 / 0; //Exception Generated
}
void method2(){
method3();
}
void method1(){
try{
method2();
} catch(Exception e){
System.out.println("Exception is handled here");
}
}
public static void main(String args[]){
ExceptionPropagation obj=new ExceptionPropagation();
obj.method1();
System.out.println("Continue with Normal Flow...");
}
}
输出
此处处理异常
继续正常流程......
仅传播未经检查的异常。抛出异常抛出 编译错误
[1] http://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html
答案 2 :(得分:5)
每当调用方法时,就会形成堆栈,并且首先从堆栈顶部抛出异常,如果没有捕获它,它将从堆栈开始向前移动,直到它没有被捕获。 如果异常在到达堆栈底部后仍然未被捕获,则它将传播到JVM并终止程序。
未经检查的异常会在java中自动传播。 计划>
public class ExceptionTest {
public static void main(String[] args) {
method1();
System.out.println("after calling m()");
}
static void method1() {
method2();
}
static void method2() {
method3();
}
static void method3() {
throw new NullPointerException();
}
}
对于传播已检查的异常,方法必须使用throws关键字抛出异常。 计划>
public class ExceptionTest {
public static void main(String[] args)
throws FileNotFoundException {
method1();
System.out.println("after calling m()");
}
static void method1() throws FileNotFoundException{
method2();
}
static void method2() throws FileNotFoundException{
method3();
}
static void method3() throws FileNotFoundException{
throw new FileNotFoundException();
}
}
传播未经检查的异常(NullPointerException)>
使用throws关键字>传播已检查的异常(FileNotFoundException)
来自:http://www.javamadesoeasy.com/2015/05/exception-propagation-in-java-deep.html
答案 3 :(得分:1)
当发生异常时,传播是一个过程,在这个过程中,异常从堆栈的顶部到底部被丢弃,然后进入要切割的调用链,如果没有被捕获,则异常再次下降到上一个方法,依此类推,直到它被捕获或直到它到达调用堆栈的最底部。这称为异常传播。
例如,假设我们的堆栈是:
C()
B()
A()
main()的
如果在c()方法中发生异常,并且如果它没有被处理,它将被传播到先前的b()方法,如果它没有在那里处理,它又被传播到处理异常的()方法,等等。
异常可以在main()方法,a()方法,b()方法或c()方法中的调用堆栈中的任何方法中处理。
回复帖子
答案 4 :(得分:0)
假设您有一个调用另一个对象的对象,然后调用另一个对象。如果在任何被调用对象中抛出异常并且未捕获该异常,则异常将传播到调用方法(如果未在任何地方捕获,则会崩溃应用程序)。
class MyClass{
void myMethod(){
A a = new A();
a.doSomething(0);
}
}
class A{
double doSomething(int n){
return 1/n;
}
}
如果执行myMethod
方法,则会在对象doSomething
的{{1}}方法中抛出异常,异常传播到堆栈中的调用方法(因此异常在此传播)示例A
的{{1}}。
答案 5 :(得分:0)
在构建程序时,发生错误的地方不是处理错误的最佳位置,即错误是在地点而不是发生地点处理的。
答案 6 :(得分:0)
如果是我们为什么需要此功能或何时使用它,则可以回答此功能的目的,
在几件事中,沿着方法调用层次结构的异常反向传播使概念@transaction得以实现,该概念是使用面向方面的编程概念自动启用的。 (@transaction有助于在Spring框架中回滚数据库)。在这里,异常传播直到调用层次结构中声明为@transaction的方法才必须自动触发数据库回滚,以后您才能处理异常。与问题无关,但@transaction仅适用于运行时异常。