自定义类要支持try-with-resources必须实现autocloseable接口并提供幂等的close()方法,该方法应释放资源、处理null或已关闭状态,并按声明逆序关闭嵌套资源,close异常会被抑制而非覆盖主异常。

要在自定义类中使用 try-with-resources,这个类必须实现 java.lang.AutoCloseable 接口(或其子接口 Closeable),并在 close() 方法中释放资源。JVM 会在 try 块结束时自动调用该方法,无论是否发生异常。
让自定义类支持 try-with-resources
只需让类实现 AutoCloseable,并提供有意义的 close() 实现:
- 接口只要求声明
void close() throws Exception,实际中建议抛出更具体的异常(如IOException),或捕获内部异常后静默处理(避免干扰主逻辑) -
close()应幂等:多次调用不报错、不重复释放(例如检查资源是否为null或已关闭) - 如果资源是其他可关闭对象(如
FileInputStream),应在自己的close()中调用它们的close()
示例:
public class DatabaseConnection implements AutoCloseable {
private final Connection conn;
public DatabaseConnection(String url) throws SQLException {
this.conn = DriverManager.getConnection(url);
}
@Override
public void close() throws SQLException {
if (conn != null && !conn.isClosed()) {
conn.close();
}
}
public void execute(String sql) throws SQLException {
try (Statement stmt = conn.createStatement()) {
stmt.execute(sql);
}
}
}
在 try-with-resources 中使用它
语法和使用标准资源完全一样:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
try (DatabaseConnection db = new DatabaseConnection("jdbc:h2:mem:")) {
db.execute("CREATE TABLE users(id INT)");
} catch (SQLException e) {
// 异常处理
}
即使 execute() 抛出异常,db.close() 仍会被自动调用。
多个资源与关闭顺序
多个资源用分号分隔,关闭顺序与声明顺序相反(后声明的先关闭):
try (ResourceA a = new ResourceA();
ResourceB b = new ResourceB();
ResourceC c = new ResourceC()) {
// ...
} // c.close() → b.close() → a.close()
这点对有依赖关系的资源很重要(比如流包装了另一个流,应先关外层)。
注意 suppressedException(被抑制异常)
如果 try 块中已抛出异常,而 close() 又抛出新异常,后者不会覆盖主异常,而是作为“被抑制异常”附加到主异常上。可通过 Throwable.getSuppressed() 获取。
- 通常无需手动处理,但调试时可打印查看:
e.printStackTrace()默认会显示被抑制异常 - 若想避免
close()抛异常干扰,可在其实现中捕获并记录(不抛出),尤其适用于清理型操作
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










