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

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

一个这样的例子是:

 try { // ... some code: A } catch(...) { // ... exception code: B } finally { // finally code: C } 

代码A将被执行。 如果一切顺利(即在A执行时没有exception被抛出),它将finally进入,因此代码C将被执行。 如果在执行A时抛出exception,则它将转到B然后最终转到C.

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

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

我得到两个不同的输出:

第一输出:

 java.lang.ArithmeticException: / by zero at substrings.main(substrings.java:15) lication.AppMain.main(AppMain.java:140) common 

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

第二输出:

  common java.lang.ArithmeticException: / by zero at substrings.main(substrings.java:15) 

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

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

如果你在catch块和finally块中写入相同的流(例如,尝试System.err.println("common") ),你会看到catch块总是在finally块之前执行,当exception是抓住。

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

 public void printStackTrace() { printStackTrace(System.err); } 

输出的格式化是因为您通过System.out.println使用标准输出流,并且System.err流发生exception

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

 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"); } }