在 catch 和 finally 子句中引发的异常

2022-08-31 06:44:27

在大学的Java问题上,有这样一段代码:

class MyExc1 extends Exception {}
class MyExc2 extends Exception {}
class MyExc3 extends MyExc2 {}

public class C1 {
    public static void main(String[] args) throws Exception {
        try {
            System.out.print(1);
            q();
        }
        catch (Exception i) {
            throw new MyExc2();
        }
        finally {
            System.out.print(2);
            throw new MyExc1();
        }
    }

    static void q() throws Exception {
        try {
            throw new MyExc1();
        }
        catch (Exception y) {
        }
        finally {
            System.out.print(3);
            throw new Exception();
        }
    }
}

我被要求给出它的输出。我回答了,但正确的答案是。这是为什么呢?我只是不明白去哪里了。13Exception in thread main MyExc2132Exception in thread main MyExc1MyExc2


答案 1

根据阅读你的答案并看到你是如何想到的,我相信你认为“进行中的例外”具有“优先级”。请记住:

当在 catch 块中引发新异常或最终从该块传播出的块时,随着新异常向外传播,当前异常将被中止(并被遗忘)。新的异常开始像任何其他异常一样展开堆栈,从当前块(catch 或 finally block)中止,并受到任何适用的 catch 或最终块的约束。

请注意,适用的捕获或最终块包括:

当在 catch 块中引发新异常时,新异常仍受该 catch 的最终块(如果有)的约束。

现在回溯执行,记住,每当您命中 时,都应中止跟踪当前异常并开始跟踪新异常。throw


答案 2

最终块中的异常将取代 catch 块中的异常。

Java 语言规范

如果 catch 块由于原因 R 而突然完成,则执行最终块。然后有一个选择:

  • 如果最终块正常完成,则 try 语句由于原因 R 而突然完成。

  • 如果最终的块由于原因 S 而突然完成,则 try 语句由于原因 S 而突然完成(并且原因 R 被丢弃)。