java 9允许在try-with-resources中直接使用已声明的effectively final局部变量,无需在try括号内重复声明;该变量必须是final或实际未被重新赋值,且类型实现autocloseable接口。

Java 9 改进了 try-with-resources 语句,允许直接使用**已经声明为 final 或等效 final(effectively final)的局部变量**,无需在 try 括号内重新声明或初始化资源。这意味着你不必把外部变量“塞进” try() 里再赋值,只要它满足资源类型(实现 AutoCloseable)且是 final / effectively final,就能直接引用。
前提条件:变量必须是 final 或 effectively final
Java 9 的增强要求该变量在作用域内**没有被重新赋值**,编译器能确认其引用不可变。例如:
final FileInputStream fis = new FileInputStream("data.txt");
try (fis) { // ✅ 合法:fis 是 final 变量,且类型 AutoCloseable
// 使用 fis
}
常见写法对比(Java 7/8 vs Java 9)
• Java 7/8 必须在 try() 内声明并初始化:
try (FileInputStream fis = new FileInputStream("data.txt")) { ... }
• Java 9 允许复用已有变量(只要符合 final 性质):
final FileInputStream fis = new FileInputStream("data.txt");
try (fis) { // ✅ 直接写变量名,不带类型、不带 =、不重复 new
...
}
支持多个外部 final 资源变量
可以在同一 try() 中列出多个符合条件的变量,用分号分隔:
final FileInputStream fis = new FileInputStream("in.txt");
final FileOutputStream fos = new FileOutputStream("out.txt");
try (fis; fos) { // ✅ 两个外部 final 变量都可直接使用
// 复制逻辑
}
注意事项和限制
-
不能是普通局部变量:如果声明时没加
final,且后续也没被重新赋值(即 effectively final),Java 9 也接受 —— 但一旦你在 try 前给它赋了新值,编译就报错。 -
不能是字段(成员变量):只适用于**方法内的局部变量**。类的
final字段、静态变量等不适用此语法。 -
类型必须是 AutoCloseable 或其子类型:比如
BufferedReader、Connection、自定义的关闭资源类。 - 仍会自动调用 close():行为与传统 try-with-resources 完全一致,异常抑制、关闭顺序(逆序)、资源释放保障都不变。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











