java中try-with-resources可同时关闭多个资源,需用分号分隔且资源须实现autocloseable接口,jvm按声明逆序自动调用close()方法,即使异常发生也保证全部关闭,java 9起支持引用外部effectively final变量。

Java 中 try-with-resources 可以同时关闭多个资源,只需在 try 后的括号内用分号 ; 分隔多个资源声明即可。所有资源必须实现 AutoCloseable 接口(包括 Closeable),JVM 会在 try 块结束时按声明**逆序**自动调用它们的 close() 方法。
语法:多个资源用分号分隔
每个资源独立声明,格式为 类型 变量名 = 初始化表达式,之间用分号隔开:
try (FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt");
BufferedReader reader = new BufferedReader(new FileReader("c.txt"))) {
// 使用资源
} // fis、fos、reader 按 reader → fos → fis 的顺序自动关闭
关闭顺序是逆序,且与异常无关
无论是否发生异常,资源都按声明的**相反顺序**关闭。例如上面例子中:
- 先关闭
reader - 再关闭
fos - 最后关闭
fis
即使某个 close() 抛出异常,后续资源仍会继续关闭;若多个 close() 都抛异常,只有第一个被抛出,其余作为“suppressed exceptions”(被抑制异常)附加到主异常上,可通过 getSuppressed() 获取。
资源变量必须是 final 或 effectively final
每个资源变量不能在 try-with-resources 括号外重新赋值,否则编译报错。但允许在 try 块内使用(只读):
// ✅ 正确:声明即初始化,未重新赋值
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "value");
ps.execute();
}
// ❌ 错误:不能在括号内对已声明变量赋值
try (Connection conn = null) { // 编译失败:conn 未初始化且非有效 final
conn = DriverManager.getConnection(url); // 不允许
也可以混合声明已有变量和新变量(需注意作用域)
如果资源已在 try 外创建,只要它是 effectively final,也可直接引用:
final FileInputStream fis = new FileInputStream("a.txt");
final FileOutputStream fos = new FileOutputStream("b.txt");
try (fis; fos) { // Java 9+ 支持这种简写形式
// 使用 fis 和 fos
} // 自动关闭
注意:这种写法要求变量本身是 final 或 effectively final,且声明在 try 外;Java 7 只支持括号内初始化,Java 9 起才支持引用已有变量的简写。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











