非常好的问题 👍

在 Java 中,finally 块最主要的作用是:

无论是否发生异常,始终执行清理或释放资源的代码。


🧩 一、finally 通常释放的资源包括:

这些资源都是**程序运行过程中占用系统资源(如文件句柄、内存、网络连接)**的对象:

常见资源类型举例释放方式
文件资源FileInputStream, FileOutputStream, FileReader, BufferedWriterclose()
数据库连接Connection, Statement, ResultSetclose()
网络资源Socket, ServerSocket, HttpURLConnectionclose()disconnect()
IO 流各种输入输出流close()
锁资源Lock(如 ReentrantLockunlock()
线程池ExecutorServiceshutdown()

🧠 二、为什么要在 finally 中释放?

因为:

  • 如果在 try 中发生异常,后续代码不会执行
  • finally 块无论是否抛出异常、是否提前 return都会执行(除非 JVM 崩溃或强制退出)。

这确保了资源不会被遗忘释放,避免:

  • 文件句柄耗尽;
  • 数据库连接泄漏;
  • 网络连接长期占用等问题。

⚙️ 三、示例代码:

FileInputStream fis = null;
try {
    fis = new FileInputStream("data.txt");
    // 读取文件内容
} catch (IOException e) {
    e.printStackTrace();
} finally {
    // 无论是否出错,都要释放文件资源
    if (fis != null) {
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


🚀 四、现代写法(推荐)—— try-with-resources

Java 7 以后,你可以不用手写 finally,让系统自动帮你关闭资源:

try (FileInputStream fis = new FileInputStream("data.txt")) {
    // 自动关闭 fis
} catch (IOException e) {
    e.printStackTrace();
}

等价于前面那段代码,但更简洁、无泄漏风险。


✅ 总结一句话:

finally 块释放的是那些占用系统资源且必须手动关闭的外部资源,例如文件流、数据库连接、网络连接、锁等。


是否希望我帮你画一张「try-catch-finally 执行流程图」?这能直观地展示 finally 在异常流程中的执行时机。