finally块一定会执行吗
结论先给出:
在大多数情况下,finally 块几乎一定会执行,但不是 100% 绝对。存在一些特殊场景会导致 finally 不执行。
下面按常见语言(以 Java 为主,顺带对比其他语言)来说明。
一、正常情况下:finally 一定会执行 ✅
try {
System.out.println("try");
} finally {
System.out.println("finally");
}
✅ 输出:
try
finally
只要程序能继续执行到 try 或 catch,finally 就会执行。
二、会导致 finally 不执行的几种情况 ❌
1️⃣ 调用 System.exit()
try {
System.out.println("try");
System.exit(0);
} finally {
System.out.println("finally");
}
❌ finally 不会执行
原因:System.exit() 会直接终止 JVM,程序直接结束。
2️⃣ JVM 崩溃 / 强制终止
以下情况 finally 也不会执行:
- JVM 崩溃(如致命错误、OOM 导致 JVM 直接挂掉)
- 操作系统强制杀死进程(
kill -9) - 断电、硬件故障
3️⃣ 守护线程(Daemon Thread)被终止
Thread t = new Thread(() -> {
try {
System.out.println("try");
} finally {
System.out.println("finally");
}
});
t.setDaemon(true);
t.start();
如果 JVM 在所有非守护线程结束后直接退出,守护线程的 finally 可能不执行。
4️⃣ 无限循环 / 死锁导致程序无法继续
try {
while (true) {}
} finally {
System.out.println("finally");
}
❌ finally 不会执行(程序永远走不到)
5️⃣ 在 try 之前就返回或抛异常
return;
try {
...
} finally {
...
}
❌ finally 根本没机会进入(代码都还没到 try)
三、finally 与 return 的执行顺序(面试常考)
int test() {
try {
return 1;
} finally {
return 2;
}
}
✅ 返回值是 2
原因:
try中的return会先“暂存返回值”- 再执行
finally finally中的return会覆盖
⚠️ 不推荐在 finally 中写 return
四、与异常的关系
try {
throw new RuntimeException();
} finally {
System.out.println("finally");
}
✅ finally 仍然会执行
异常会在 finally 执行后继续抛出。
五、其他语言对比
| 语言 | finally 是否一定执行 |
|---|---|
| Java | ✅ 基本一定(除 JVM 退出) |
| C# | ✅ 类似 Java |
| Python | ✅(除非进程被强杀) |
| JavaScript | ✅(同步代码) |
| Go | ❌ 没有 finally,用 defer(defer 也可能不执行) |
六、一句话总结(面试版)
finally块在程序正常执行到try/catch且 JVM 未被强制终止的情况下一定会执行,但在System.exit()、JVM 崩溃、守护线程被终止等特殊情况下可能不会执行。
如果你愿意,我可以帮你整理一份 finally 面试题速记版 或 结合 try-catch-finally + return 的流程图。