📜  Java中的异常传播

📅  最后修改于: 2022-05-13 01:55:33.814000             🧑  作者: Mango

Java中的异常传播

先决条件: Java中的异常,已检查与未检查的异常

异常传播:首先从栈顶抛出异常,如果没有被捕获,则将调用栈下拉到前一个方法。
在方法抛出异常后,运行时系统会尝试找到一些东西来处理它。处理异常的一组可能的“东西”是已调用的方法的有序列表,以获取发生错误的方法。方法列表称为调用堆栈,搜索方法是异常传播。

未经检查的异常中的异常传播

当异常发生时,传播是一个将异常从堆栈顶部丢弃到底部的过程。如果一次没有被捕获,异常会再次下降到前一个方法,依此类推,直到它被捕获或到达调用堆栈的最底部。这称为异常传播,这发生在未经检查的异常的情况下。

在下面的示例中,异常发生在未处理的 m() 方法中,因此将其传播到未处理的先前 n() 方法,再次传播到处理异常的 p() 方法。
异常可以在调用堆栈中的任何方法中处理,无论是 main() 方法、p() 方法、n() 方法还是 m() 方法。

注意:默认情况下,未经检查的异常在调用链中转发(传播)。

// Java program to illustrate
// unchecked exception propagation
// without using throws keyword
class Simple {
    void m()
    {
        int data = 50 / 0; // unchecked exception occurred
        // exception propagated to n()
    }
  
    void n()
    {
        m();
        // exception propagated to p()
    }
  
    void p()
    {
        try {
            n(); // exception handled
        }
        catch (Exception e) {
            System.out.println("Exception handled");
        }
    }
  
    public static void main(String args[])
    {
        Simple obj = new Simple();
        obj.p();
        System.out.println("Normal flow...");
    }
}

输出:

Exception handled 
Normal flow...

检查异常中的异常传播

与 Unchecked Exceptions 不同,Checked Exception 的情况下不会发生异常传播,并且在此处必须使用 throw 关键字。仅传播未经检查的异常。检查的异常抛出编译错误。

在下面的示例中,如果我们在 m() 和 n() 函数中省略 throws 关键字,编译器将生成编译时错误。因为与未经检查的异常不同,检查的异常在不使用 throws 关键字的情况下无法传播。

注意:默认情况下,检查的异常不会在调用链中转发(传播)。

// Java program to illustrate exception propagation
// in checked exceptions  and it can be propagated
// by throws keyword ONLY
import java.io.IOException;
class Simple {
  
    // exception propagated to n()
    void m() throws IOException
    {
        // checked exception occurred
        throw new IOException("device error");
    }
  
    // exception propagated to p()
    void n() throws IOException
    {
        m();
    }
    void p()
    {
        try {
  
            // exception handled
            n();
        }
        catch (Exception e) {
            System.out.println("exception handled");
        }
    }
  
    public static void main(String args[])
    {
        Simple obj = new Simple();
        obj.p();
        System.out.println("normal flow...");
    }
}

输出:

exception handled 
normal flow...