非常好的问题 👍
在 Java 中,finally 块最主要的作用是:
✅ 无论是否发生异常,始终执行清理或释放资源的代码。
🧩 一、finally 通常释放的资源包括:
这些资源都是**程序运行过程中占用系统资源(如文件句柄、内存、网络连接)**的对象:
| 常见资源类型 | 举例 | 释放方式 | 
|---|---|---|
| 文件资源 | FileInputStream, FileOutputStream, FileReader, BufferedWriter 等 | close() | 
| 数据库连接 | Connection, Statement, ResultSet | close() | 
| 网络资源 | Socket, ServerSocket, HttpURLConnection | close() 或 disconnect() | 
| IO 流 | 各种输入输出流 | close() | 
| 锁资源 | Lock(如 ReentrantLock) | unlock() | 
| 线程池 | ExecutorService | shutdown() | 
🧠 二、为什么要在 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 在异常流程中的执行时机。
发表回复