java - 为什么finally block 执行与未捕获的异常不一致

标签 java exception jvm threadpool try-catch-finally

我最近在一次采访中被问到关于java中异常情况的执行顺序,如果异常没有被捕获并传播回调用代码,有finally block ,那么是否会打印finally block 语句? 如果是的话,它们是在异常之前还是之后打印的?

我尝试运行此场景,发现输出不一致。

我尝试过的代码是:

公共(public)类FinallyExecution{

public static void main(String[] args) {

    try{

        FinallyExecution.divide(100, 0);

    }finally{
        System.out.println("finally in main");
    }

}

public static void divide(int n, int div){

    try{
        int ans = n/div;
    }
    finally{
        System.out.println("finally of divide");
    }
}

}

不一致的输出是:

一次:

Exception in thread "main" java.lang.ArithmeticException: / by zero at exceptions.FinallyExecution.divide(FinallyExecution.java:20) at exceptions.FinallyExecution.main(FinallyExecution.java:9) finally of divide finally in main

下一个:

finally of divide finally in main Exception in thread "main" java.lang.ArithmeticException: / by zero at exceptions.FinallyExecution.divide(FinallyExecution.java:20) at exceptions.FinallyExecution.main(FinallyExecution.java:9)

那么在这种情况下到底发生了什么? JVM 是执行finally block 然后异常退出,还是按照相反的顺序? 无论哪种情况,为什么输出不一致?

最佳答案

您正在打印到System.out,而未捕获的异常堆栈跟踪则打印到System.err。您可以在控制台中看到这两个内容,但未定义顺序。

如果您将调试打印更改为使用 System.err,则顺序是一致的。

关于java - 为什么finally block 执行与未捕获的异常不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34050332/

相关文章:

java - 我在哪里可以找到 "reference barcodes"来验证条码库输出?

java - ResourceAccessException 内 SocketTimeout 异常的 Junit 代码覆盖率

java - 捕获方法内部方法抛出的异常

java - 如何调整G1GC以减小内存占用?

java - 在 Java 中嵌入 CPython 时,为什么会挂起?

java - NDK 在 Android 中如何工作——NDK、JNI 等的使用顺序是什么?

java - Azure 存储 Java API : Account does not support HTTP

java - 在数组中使用文本文件。文本文件有 15 行,名称和 4 个分数重复 3 次。无法获取数组来抓取文本数据

java - 获取 DIY 链表类以抛出异常

c - 如何让 VC++ 的调试器在出现异常时中断?