未捕获的RuntimeException和finally子句:哪个先来?

cha*_*nce 12 java try-catch-finally runtimeexception

当子句调用时,A RuntimeException被抛出try而没有被捕获.finallySystem.exit()

public static void main(String[] args) {
    try {
        Integer.valueOf("NotANumber");
    } finally {
        System.out.println("finally");
        System.exit(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是

finally
Run Code Online (Sandbox Code Playgroud)

如果System.exit(0)从finally中删除,则输出为

finally
Exception in thread "main" java.lang.NumberFormatException: For input string: "NotANumber"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Integer.parseInt(Integer.java:449)
    at java.lang.Integer.valueOf(Integer.java:554)
    at exception.MyExcepTest.main(MyExcepTest.java:20)
Run Code Online (Sandbox Code Playgroud)

"终于"可能出现之前,之后或在的meesage之间NumberFormatException.

任何人都可以解释一下吗?

Thi*_*ilo 15

在main方法退出之前肯定会执行finally块,之后由JVM打印堆栈跟踪.

也许堆栈跟踪被打印到System.err,并且两个流以不可预测的方式混合在您的控制台输出中(因为它们基本上同时生成).

当你"最终"打印到System.err时会发生什么?

  • 不是"可能".这就是你看到这个的原因.未捕获的异常将打印到错误流.未定义订单的原因是因为它将是您的控制台,它依赖于首先刷新哪个缓冲区. (3认同)
  • 好吧,如果我将"finally"打印到System.err,它似乎总是在stacktrace之前出现. (2认同)

dku*_*mar 7

事情是,当抛出一个异常时...... JVM第一次执行代码,内部finally块,然后抛出异常,如果被捕获,它将抛出异常并终止线程.所以这里当finally.block中存在System.exit(0)时,它立即终止线程,因此JVM没有机会抛出异常.所以输出只是"终于"