Java 9允许try-with-resources直接使用已声明的final或effectively final变量,无需重复声明初始化,支持多资源用分号分隔,但要求变量作用域覆盖整个try且类型实现AutoCloseable。

Java 9 对 try-with-resources 做了一项实用改进:允许在 try 语句中直接使用**已声明的 final 或 effectively final 的变量**,无需重复声明和初始化。这减少了冗余代码,让资源管理更简洁。
Java 8 的写法(对比参考)
在 Java 8 中,资源必须在 try 括号内声明并初始化:
InputStream is = new FileInputStream("file.txt");
try (InputStream inputStream = is) { // 必须重新声明+赋值
// 使用 inputStream
} catch (IOException e) {
// 处理异常
}
即使 is 已是 final,也不能直接写 try (is),否则编译失败。
Java 9 的简化写法
Java 9 允许将已存在的、effectively final 的资源变量直接放在 try 括号中:
立即学习“Java免费学习笔记(深入)”;
final InputStream is = new FileInputStream("file.txt");
try (is) { // ✅ 合法:直接使用变量名
// 使用 is
}
只要变量满足以下任一条件即可:
- 显式声明为
final - 虽未加
final,但在初始化后**从未被重新赋值**(即 effectively final)
多个资源的简化用法
多个已声明资源可一起写入括号,用分号分隔:
final InputStream is = new FileInputStream("in.txt");
final OutputStream os = new FileOutputStream("out.txt");
try (is; os) { // ✅ Java 9 支持
// 复制逻辑
}
注意:分号是必需的,不能用逗号;每个变量仍需是 effectively final。
注意事项与常见误区
这个特性只改变语法便利性,不改变资源关闭行为或异常处理逻辑。需注意:
- 变量作用域必须覆盖整个 try 语句(不能在 try 内部声明再引用)
- 不能用于非 effectively final 变量,例如后续有
is = null;就会报错 - 仍要求资源类型实现
AutoCloseable - 异常抑制(suppression)机制与 Java 7/8 完全一致


















