16

什么是异常传播?我试图谷歌它,但找不到令人满意的结果。最好用Java来解释这一点。

4

7 回答 7

20

令人惊讶的是,在关于异常的 Java 教程页面中对此进行了解释。

异常从一个方法传播到另一个方法,沿着调用堆栈向上传播,直到它被捕获。因此,如果a()调用b(),调用c(),调用d(),并且如果d()抛出异常,则异常将从 d 传播到 c 到 b 到 a,除非这些方法之一捕获到异常。

于 2012-05-17T10:14:16.697 回答
15

简短回答:未捕获的异常在调用堆栈中传播,直到堆栈变空,这种传播称为异常传播。

长答案: 方法抛出异常后,运行时系统在调用堆栈中搜索包含可以处理异常的代码块(异常处理程序)的方法。搜索从发生错误的方法开始,并以调用方法的相反顺序通过调用堆栈进行。当找到合适的处理程序时,运行时系统会将异常传递给处理程序。此外,还有一个值得注意的点:

可以说,我们有一个方法链,其中 method3() 调用 method2(),method2() 调用 method1()。所以当

1) 在method3() 中发生异常,在method3() 中我们没有任何异常处理程序。

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

于 2014-12-09T05:41:30.183 回答
7

每当调用方法时,都会形成堆栈,并且首先从堆栈顶部抛出异常,如果未捕获,它将开始向下堆栈到先前的方法,直到未捕获为止。如果异常即使在到达堆栈底部后仍未被捕获,它会传播到 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) > 传播未经检查的异常 (NullPointerException)

使用 throws 关键字传播检查的异常 (FileNotFoundException) > 使用 throws 关键字传播检查异常 (FileNotFoundException)

来自:http ://www.javamadesoeasy.com/2015/05/exception-propagation-in-java-deep.html

于 2015-05-13T11:07:47.813 回答
1

当异常发生时,传播是一个过程,其中异常从堆栈顶部到底部并进入调用链以被剪切,如果没有在那里捕获,则异常再次下降到前一个方法,依此类推,直到它被捕获或到达调用堆栈的最底部。这称为异常传播。

例如假设我们的堆栈是:

C()

b()

一种()

主要的()

如果在 c() 方法中发生异常并且如果它没有被处理,它将被传播到之前的 b() 方法,如果它没有在那里处理,它再次被传播到处理异常的 a() 方法等等。

异常可以在调用堆栈中的任何方法中处理,无论是 main() 方法、a() 方法、b() 方法还是 c() 方法。

回复主题

于 2017-01-29T15:33:34.473 回答
0

假设您有一个对象调用另一个对象,然后该对象调用另一个对象。如果在任何被调用的对象中抛出异常并且它没有被捕获,那么异常就会传播到调用方法(如果在任何地方都没有被捕获,则应用程序崩溃)。

class MyClass{

 void myMethod(){
   A a = new A();
   a.doSomething(0);
 }

}

class A{

  double doSomething(int n){
   return 1/n;
  }

}

如果myMethod执行了方法,就会在doSomethingobject 的方法中抛出异常A,并且异常传播到堆栈中的调用方法(因此在本例中异常传播到myMethodof myClass)。

于 2012-05-17T10:18:55.800 回答
0

在构建程序时,错误发生的地方并不是处理它的最佳位置,即错误是在错误发生的地方而不是错误发生的地方处理的。

于 2014-05-23T14:30:08.063 回答
0

如果我们为什么需要这个功能或者我们什么时候使用它,这反过来又可以回答这个功能的目的,

在几件事中,异常反向传播沿方法调用层次结构向后传播启用了 @transaction 概念,该概念是使用面向方面的编程概念自动启用的。(@transaction 有助于在 Spring 框架中回滚数据库)。在调用层次结构中声明 @transaction 的方法之前,异常传播必须自动触发 DB 回滚,然后您可以处理异常。与问题无关,但 @transaction 仅适用于运行时异常。

于 2020-01-10T12:22:20.847 回答