在 Java 中阻止 Finally 块执行的有效命令

Valid Commands That Keep A Finally-block From Executing in Java

所以我被分配去教授关于异常处理的块,我 运行 遇到了一个我没有答案的问题。 Java 中的哪些有效(例如,不会导致编译器或 运行 时间错误)命令会阻止 finally 块执行?

return 语句不会,但 System.exit(0) 语句会。我的理解是 finally 块无论如何都会执行。哪些(有效的)语句会阻止 finally 块这样做,为什么?

引用 Docs:

If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.

关于你关于 System.exit() 的例子,再次引用 Docs

Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.

表示finally不会执行

简单示例:

try {
    System.out.println("try");
    System.exit(0);
} finally {
    System.out.println("finally");
}

上面的例子只会打印 try 而不会打印 finally

引用Oracle's tutorials:

Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.

System.exit 将与 JVM 完全相同,从而防止 finally 块来自 运行,这也会从另一个线程中杀死包含该块的线程。另一个极端情况是 try 块中有一个无限循环,这只会阻止它结束,因此永远不会到达 finally 循环。

我看到三种情况永远不会到达 finally 块(或堆栈帧中的任何进一步指令):

  1. 线程突然死亡(包括JVM退出)
  2. 栈帧操作
  3. 无限循环;无论它是主动的 (while (true)) 还是被动的(获取锁、等待通知等)

只有本机代码(包括自己的 JVM 机制)才应该终止线程或使用堆栈帧。致命的系统错误也是一种选择。

但是,JVM 实现可以在他的特定 API(即 sun.misc.Unsafe)或通过丑陋的 Java SE API(即Thread.destroy