什么是异常传播?

时间:2012-05-17 10:10:11

标签: java c++ exception-handling

  

什么是异常传播

我在谷歌尝试但对结果不满意。如果可能的话,还请举一些例子来解释。 C ++,php和java语言更可取。

7 个答案:

答案 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(),在那里它会找到异常处理程序。

enter image description here

示例:

 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] http://www.c4learn.com/java/java-exception-propagation/

答案 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)> Propagating unchecked exception (NullPointerException)

使用throws关键字>传播已检查的异常(FileNotFoundException) Propagating checked exception (FileNotFoundException) using throws keyword

来自: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仅适用于运行时异常。