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

2022-09-03 08:47:20

我试图理解执行流是如何工作的。Stack Overflow 用户提供了几个关于其执行流的解决方案。try-catch-finally

一个这样的例子是:

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

代码 A 将被执行。如果一切顺利(即在 A 执行时没有抛出异常),它将转到 ,因此代码 C 将被执行。如果在执行 A 时引发异常,则它将转到 B,最后转到 C。finally

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

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)

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


答案 1

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

如果在捕获块和最终块中写入同一流(例如,尝试),您将看到捕获块始终在捕获异常时在 final 块之前执行。System.err.println("common")


答案 2

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

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

发生输出格式的原因是您正在使用标准输出流,并且发生异常流System.out.printlnSystem.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");
       }
  }

推荐