195. Java 异常 - finally 块:Java 中的“兜底侠”
文章目录
- 195. Java 异常 - finally 块:Java 中的“兜底侠”
- 💡 finally 是什么?
- ✅ 使用场景
- 🔍 示例讲解:writeList 方法的 finally
- 📌 可能的三种退出方式:
- ⚠️ 注意事项
- 1. ❗ `JVM `崩溃时` finally` 不保证执行
- 2. ❗ finally 中的异常不能被忽视
- 🌱 `Java 7` 提示:`try-with-resources` 更优雅!
- 🧠 小结
195. Java 异常 - finally 块:Java 中的“兜底侠”
💡 finally 是什么?
finally
块无论 try
块是否抛出异常,总会被执行。这是它最强大的地方。也正因为如此,它成为我们做资源清理时最可靠的方式。
✅ 使用场景
为什么我们需要 finally?
- ✅ 防止 忘记关闭资源
- ✅ 即使
try
里面有return/continue/break
,finally
仍会执行! - ✅ 不管是 正常流程 还是 异常流程,清理代码都不会被跳过
🔍 示例讲解:writeList 方法的 finally
PrintWriter out = null;
try {out = new PrintWriter(new FileWriter("OutFile.txt"));for (int i = 0; i < SIZE; i++) {out.println("Value at: " + i + " = " + list.get(i));}
} catch (IOException | IndexOutOfBoundsException e) {System.err.println("Exception: " + e.getMessage());
} finally {if (out != null) {System.out.println("Closing PrintWriter");out.close();} else {System.out.println("PrintWriter not open");}
}
📌 可能的三种退出方式:
new FileWriter(...)
抛出IOException
list.get(i)
抛出IndexOutOfBoundsException
- 所有代码正常执行完毕
✅ 不论哪种情况,finally
都会执行,确保 PrintWriter
被关闭,避免资源泄漏。
⚠️ 注意事项
1. ❗ JVM
崩溃时 finally
不保证执行
System.exit(1); // 一旦调用此方法,finally 也不执行!
所以不要依赖 finally
去写非常关键的业务逻辑,比如“写入数据库”或“发送日志服务”。
2. ❗ finally 中的异常不能被忽视
如果 finally
中再抛异常,而 try
或 catch
中也有异常,那么 finally
的异常会覆盖前面的异常信息,造成调试困难。
👉 建议在 finally
中加 try-catch
,确保异常被妥善处理:
finally {try {if (out != null) out.close();} catch (IOException e) {System.err.println("Error closing writer: " + e.getMessage());}
}
🌱 Java 7
提示:try-with-resources
更优雅!
从 Java 7
开始,如果你操作的是 Closeable
或 AutoCloseable
的资源(比如 FileWriter
、Scanner
、Socket
等),可以使用 try-with-resources
自动关闭它们,代码更简洁,风险更低!
👀 我们稍后会详细介绍!
- “finally 就像 Java 中的保底侠,确保你永远不会‘忘了关灯’。”
- “它最大的价值不是处理异常,而是保障资源一定被释放。”
- “finally 可以执行 return、break、continue 之后的收尾动作,这点特别容易被忽视。”
🧠 小结
特性 | 说明 |
---|---|
执行时机 | 无论是否抛异常,finally 都执行 |
使用目的 | 做资源释放、清理现场等工作 |
注意事项 | 避免在 finally 抛新异常、避免依赖它做关键逻辑 |
更优选择 | Java 7 起推荐使用 try-with-resources |