Java中推荐使用try-with-resources自动释放资源,它能确保实现AutoCloseable接口的资源在try块结束时自动关闭,并妥善处理关闭异常;若必须用finally,则需判空、独立捕获关闭异常以防掩盖主异常。

Java 中通过 try-catch-finally 捕获异常并释放资源,核心在于确保资源(如文件流、数据库连接、网络套接字等)无论是否发生异常都得到关闭。但需注意:finally 块中关闭资源本身也可能抛出异常,需妥善处理,否则会掩盖原始异常。
基本结构:try-catch-finally 释放资源
传统方式是在 finally 块中手动调用 close() 等方法:
- 在
try块中打开资源、执行可能出错的逻辑 - 在
catch块中处理特定异常(如IOException) - 在
finally块中检查资源是否为null,再调用close()
示例:
InputStream is = null;
try {
is = new FileInputStream("data.txt");
// 读取数据...
} catch (IOException e) {
System.err.println("读取失败:" + e.getMessage());
} finally {
if (is != null) {
try {
is.close(); // close 可能抛 IOException
} catch (IOException e) {
System.err.println("关闭流失败:" + e.getMessage());
}
}
}
推荐写法:使用 try-with-resources(Java 7+)
try-with-resources 是更安全、简洁的替代方案,它自动管理实现了 AutoCloseable 接口的资源,无需手动写 finally,且能正确处理多个异常(如业务异常 + 关闭异常):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 资源声明写在
try后的括号内,用分号分隔 - 资源会在
try块结束时(无论正常完成还是异常退出)自动调用close() - 若
try块抛异常,且close()也抛异常,则后者作为“被抑制异常(suppressed exception)”附加到主异常上,可通过getSuppressed()获取
示例:
try (FileInputStream is = new FileInputStream("data.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
String line = reader.readLine();
// 处理数据...
} catch (IOException e) {
System.err.println("操作失败:" + e.getMessage());
// 若 close() 也失败,异常会被抑制,不掩盖此处的 e
}
finally 中释放资源的注意事项
如果因兼容旧版本或特殊场景必须用 finally,请牢记:
- 资源变量需声明在
try外(如InputStream is = null;),否则作用域不可达 - 关闭前必须判空,避免
NullPointerException - 关闭操作自身要包裹在独立的
try-catch中,防止掩盖try块中的原始异常 - 多个资源需分别关闭,并各自处理其关闭异常(不能共用一个
catch)
资源释放的本质是“确定性终结”
Java 不保证 finalize() 何时执行,也不推荐依赖它。释放资源的关键是:谁创建,谁负责及时关闭;谁持有,谁确保终结。无论是 try-with-resources 还是手动 finally,目标都是让资源生命周期清晰可控,避免内存泄漏、文件句柄耗尽或数据库连接池打满等问题。

















