Java中try-with-resources管理多个资源需按依赖顺序声明并用分号分隔,资源须实现AutoCloseable接口,JVM逆序调用close();Java 9起支持引用外部final变量。

Java 中用 try-with-resources 同时管理多个资源对象,核心是把它们**按依赖关系写在 try 括号里,用分号隔开**,JVM 会自动按声明的逆序调用 close(),既安全又省心。
资源必须实现 AutoCloseable 接口
只有实现了 java.lang.AutoCloseable(或其子接口 java.io.Closeable)的类才能被自动管理。常见类型包括:
-
FileInputStream/FileOutputStream -
BufferedReader/BufferedWriter -
Connection、PreparedStatement、ResultSet -
Socket、ServerSocket
自定义类只要重写 close() 方法并声明抛出 Exception,也能纳入管理。
多个资源的声明格式和顺序很关键
语法要求严格:每个资源必须是独立、完整声明,类型 + 变量名 + 初始化表达式,**不能用逗号,只能用分号分隔**;且声明顺序直接影响关闭安全。
立即学习“Java免费学习笔记(深入)”;
- ✅ 正确(底层流先声明,包装流后声明):
try (FileInputStream fis = new FileInputStream("a.txt");<br> BufferedInputStream bis = new BufferedInputStream(fis);<br> OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"))) { ... }
关闭顺序:osw → bis → fis(逆序),确保包装流不会在底层流关闭后再调用close()。 - ❌ 错误(单行嵌套创建,底层流无法单独管理):
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"))) { ... }
底层FileInputStream没有独立变量,JVM 无法保证它被关闭。 - ❌ 错误(复用变量或赋值语句):
BufferedReader br;<br> try (br = new BufferedReader(...)) { ... }—— 编译不通过,缺少类型声明。
异常处理机制保障主逻辑不被掩盖
如果 try 块抛异常,同时某个 close() 也抛异常,JVM 不会覆盖主异常,而是把关闭异常作为“被抑制异常”(suppressed exception)附加到主异常上。
- 主异常仍正常抛出,调用方能第一时间看到业务问题
- 可通过
exception.getSuppressed()获取所有被压制的关闭异常 - 即使多个
close()连续失败,JVM 也会继续执行后续关闭,不中断流程
Java 9 起支持已声明的 final 变量
Java 9 放宽了限制:如果资源变量已在外部声明为 final 或“事实 final”(effectively final),可以直接在 try 括号中引用:
- ✅ Java 9+ 允许:
final BufferedReader br = new BufferedReader(...);<br> try (br) { ... } - ❌ Java 8 及以前不支持,必须在括号内完成声明和初始化


















