195. Java 异常 - finally 块:Java 中的“兜底侠”

195. Java 异常 - finally 块:Java 中的“兜底侠”


💡 finally 是什么?

finally 块无论 try 块是否抛出异常,总会被执行。这是它最强大的地方。也正因为如此,它成为我们做资源清理时最可靠的方式。


✅ 使用场景

为什么我们需要 finally?

  • ✅ 防止 忘记关闭资源
  • ✅ 即使 try 里面有 return/continue/breakfinally 仍会执行!
  • ✅ 不管是 正常流程 还是 异常流程,清理代码都不会被跳过

🔍 示例讲解: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");
    }
}

📌 可能的三种退出方式:

  1. new FileWriter(...) 抛出 IOException
  2. list.get(i) 抛出 IndexOutOfBoundsException
  3. 所有代码正常执行完毕

✅ 不论哪种情况,finally 都会执行,确保 PrintWriter 被关闭,避免资源泄漏。


⚠️ 注意事项

1. ❗ JVM崩溃时finally 不保证执行

System.exit(1); // 一旦调用此方法,finally 也不执行!

所以不要依赖 finally 去写非常关键的业务逻辑,比如“写入数据库”或“发送日志服务”。


2. ❗ finally 中的异常不能被忽视

如果 finally 中再抛异常,而 trycatch 中也有异常,那么 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 开始,如果你操作的是 CloseableAutoCloseable 的资源(比如 FileWriterScannerSocket 等),可以使用 try-with-resources 自动关闭它们,代码更简洁,风险更低!

👀 我们稍后会详细介绍!


  • “finally 就像 Java 中的保底侠,确保你永远不会‘忘了关灯’。”
  • “它最大的价值不是处理异常,而是保障资源一定被释放。”
  • “finally 可以执行 return、break、continue 之后的收尾动作,这点特别容易被忽视。”

🧠 小结

特性 说明
执行时机 无论是否抛异常,finally 都执行
使用目的 做资源释放、清理现场等工作
注意事项 避免在 finally 抛新异常、避免依赖它做关键逻辑
更优选择 Java 7 起推荐使用 try-with-resources
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容