Java中finally块不执行的四种情况:一是System.exit()导致JVM立即终止;二是线程被Thread.stop()强杀或中断后阻塞未响应;三是JVM崩溃、系统kill-9或硬件故障等底层异常;四是finally内部抛出未处理异常或调用System.exit()。
在Java中,finally块几乎总是会执行,但“几乎”意味着存在少数明确的例外情况——这些场景下,finally确实不会被执行。理解这些边界条件,对编写健壮、可预测的资源清理逻辑至关重要。
当代码中调用System.exit(int status)时,JVM会立即终止当前进程,所有未完成的字节码(包括try-catch-finally中的finally)都会被跳过。
如果执行try-finally的线程在进入finally前被Thread.stop()(已废弃但仍有遗留调用)或外部信号强杀,finally可能丢失。更现实的情况是:线程在finally之前陷入无限等待(如Object.wait()、LockSupport.park()),而此时线程被interrupt(),但代码未检查中断状态并提前退出,导致逻辑卡住——看似“没执行”,实则是阻塞而非跳过。
溃或底层系统故障例如发生OutOfMemoryError导致JVM核心崩溃、操作系统kill -9强杀进程、断电、硬件故障等。这类属于非Java可控的系统级异常,finally自然无法运行。
如果finally块自身抛出异常(如NullPointerException)、错误(如StackOverflowError),或者调用了System.exit(),那么它“开始执行了”,但未能“完整执行完毕”。此时外层调用栈可能被截断,看起来像finally“没起作用”。