Try-catch-finally执行顺序似乎是随机的

moh*_*abu 15 java exception-handling exception

我试图了解try-catch-finally执行流程的工作原理.Stack Overflow用户有一些关于其执行流程的解决方案.

一个这样的例子是:

try {
    // ... some code: A
} 
catch(...) {
    // ... exception code: B
} 
finally {
    // finally code: C
}
Run Code Online (Sandbox Code Playgroud)

代码A将被执行.如果一切顺利(即在执行A时没有异常被抛出),它将会转到finally,因此代码C将被执行.如果在执行A时抛出异常,那么它将转到B然后最终转到C.

但是,当我尝试时,我得到了不同的执行流程:

try {
    int a=4;
    int b=0;
    int c=a/b;
}
catch (Exception ex)
{
    ex.printStackTrace();
}
finally {
    System.out.println("common");
}
Run Code Online (Sandbox Code Playgroud)

我得到两个不同的输出:

第一输出:

java.lang.ArithmeticException: / by zero
at substrings.main(substrings.java:15)
lication.AppMain.main(AppMain.java:140)
common
Run Code Online (Sandbox Code Playgroud)

但是,当我第二次运行相同的程序时:

第二输出:

 common
    java.lang.ArithmeticException: / by zero
    at substrings.main(substrings.java:15)
Run Code Online (Sandbox Code Playgroud)

我应该从中得出什么结论?它是随机的吗?

Era*_*ran 41

printStackTrace()输出到标准误差.System.out.println("common")输出到标准输出.它们都被路由到同一个控制台,但它们在该控制台上出现的顺序不一定是它们执行的顺序.

如果你写在两个catch块同样的流finally块(例如,尝试System.err.println("common")),你会看到,当之前捕获异常finally块catch块总是执行.


Kum*_*nav 7

异常的printstacktrace()方法源代码(在Throwable类中定义)

public void printStackTrace() {
        printStackTrace(System.err);
    }
Run Code Online (Sandbox Code Playgroud)

输出的格式化是因为您正在使用标准输出流System.out.println而异常发生System.err

尝试使用一个变量来检查异常并在异常发生时在同一个错误控制台中打印: -

boolean isException = false;
try {
        int a=4;
        int b=0;
        int c=a/b;
    }
    catch (Exception ex)
    {
       isException = true
       ex.printStackTrace();
    }
    finally {
       if(isException){
        System.err.println("common");
       }else{
        System.out.println("common");
       }
  }
Run Code Online (Sandbox Code Playgroud)