3

对 catch 和 finally 块中抛出的异常有疑问:

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) {
            System.out.print(3);
        }
        finally {
            System.out.print(4);
            throw new Exception();
        }
    }

}

我曾多次尝试执行上述代码。它每次都给我不同的输出。

output 1: 1Exception in thread "main" 342test.MyExc1
at test.C1.main(C1.java:18)
output 2: 1342Exception in thread "main" test.MyExc1
at test.C1.main(C1.java:18)
output 3: 1Exception in thread "main" test.MyExc1
342 at test.C1.main(C1.java:18)
output4:  1Exception in thread "main" 34test.MyExc1
2 at test.C1.main(C1.java:18)

请解释。

4

1 回答 1

11

您所看到的只是写入System.out和之间的竞争条件System.err。您使用 1、3、4、2 显式调用System.out.print,异常被抛出并System.err自动转储。因此,您得到的每个输出都是“1342”,其中某处有异常堆栈跟踪。

在每种情况下,实际的执行流程都是相同的——只是输出不同。为了证明这一点,您可以将整个 main 方法包装在一个try/catch块中,该块将异常写入System.out,此时它将与所有现有System.out调用同步,并且没有竞争条件。

于 2016-12-15T09:41:42.603 回答