在 jdk 9 中,如果 try-with-resources 语句中的资源变量已经是 final 或 effectively final(即初始化后未被修改),可以直接在 try 括号中引用该变量,无需重新声明。这允许复用已创建的资源对象,简化代码结构并避免重复实例化。

JDK 8 与 JDK 9 的语法差异
JDK 8 要求必须在 try 括号内声明并初始化资源,即使变量已在外部定义。JDK 9 放宽了这一限制,允许直接引用外部 effectively final 变量。这种变化使得资源管理更加灵活,特别是在资源对象需要被多个部分共享或预先配置的场景下。

import java.io.*;
public class ResourceDemo {
public static void main(String[] args) throws IOException {
// JDK 9+ 方式:直接引用 effectively final 变量
BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
try (reader) {
String line = reader.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
}
}非 effectively final 变量的处理方式
如果资源变量在初始化后被修改过,它就不再是 effectively final,此时不能在 try-with-resources 中直接引用。必须重新声明一个新变量或在 try 括号内重新初始化。这是为了确保资源在关闭时状态一致,避免潜在的资源泄漏或错误关闭。
立即学习“Java免费学习笔记(深入)”;

import java.io.*;
public class NonFinalResourceDemo {
public static void main(String[] args) throws IOException {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("input.txt"));
// 模拟变量被修改
reader = new BufferedReader(new InputStreamReader(System.in));
// JDK 8 兼容方式:在 try 括号内重新声明
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
}
}
}资源关闭的实际行为验证
无论使用 JDK 8 还是 JDK 9 的方式,try-with-resources 都会在 try 块结束时自动调用资源的 close() 方法。对于 implements AutoCloseable 接口的类,close() 方法的执行顺序与声明顺序相反。如果 close() 抛出异常,这些异常会被 suppressed 到原始异常中,确保主逻辑的异常信息不被掩盖。


















