try-with-resources是比手动finally更简洁安全的资源管理方案,编译器自动调用close(),要求资源实现autocloseable接口,按声明逆序关闭,异常被抑制并可获取,支持与catch/finally组合使用。

Java 的 try-with-resources 是比手动写 finally 释放资源更简洁、安全的替代方案,核心在于让编译器自动调用 close(),避免忘记关闭、异常屏蔽、冗余代码等问题。
资源必须实现 AutoCloseable 接口
只有实现了 AutoCloseable(或其子接口 Closeable)的类才能用于 try-with-resources。常见如 FileInputStream、BufferedReader、Connection、PreparedStatement 等都已支持。
- 自定义资源类只需重写
close()方法,并确保幂等性和异常处理得当 - 不要在
close()中抛出未检查异常以外的异常,否则可能干扰主流程
语法简洁,自动管理生命周期
资源声明直接写在 try 后的括号里,JVM 保证无论是否发生异常,都会按声明逆序调用 close()。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
try (FileInputStream fis = new FileInputStream("a.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
String line = reader.readLine();
// 处理逻辑
} // ← 这里自动调用 reader.close() 和 fis.close()
- 多个资源用分号隔开,关闭顺序与声明顺序相反(后声明的先关闭)
- 无需显式 catch 或 finally,也不用手动判空调用 close()
- 即使 try 块中抛出异常,close() 仍会执行;若 close() 也抛异常,会被抑制(suppressed),可通过
getSuppressed()获取
兼容原有 try-catch 结构
try-with-resources 可与 catch、finally 自由组合,逻辑更清晰:
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "name");
ps.execute();
} catch (SQLException e) {
logger.error("DB operation failed", e);
} // finally 不再需要 —— 资源已自动释放
- 异常处理聚焦业务逻辑,资源管理交给语法机制
- 如果确实需要在 finally 中做非资源清理的事(比如重置状态、打日志),仍可保留 finally 块,它会在资源关闭后执行
注意嵌套资源和不可关闭场景
不是所有“类似资源”的对象都适合 try-with-resources。例如:
- 某些流包装器(如
BufferedInputStream)关闭时会连带关闭底层流,重复声明可能导致二次关闭异常 - 线程、数据库连接池中的连接通常不应由业务代码主动 close,而是调用
return或close()归还池 —— 此时用 try-with-resources 反而错误 - 若资源获取本身可能失败(如构造函数抛异常),需确保该异常能被上层捕获,因为 try-with-resources 的初始化阶段异常不会进入 catch 块的常规流程
不复杂但容易忽略:只要资源可关闭、作用域明确、生命周期限于当前逻辑块,try-with-resources 就是比 finally 更优雅的选择。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










