Java中try-with-resources语句支持在try括号内用分号分隔声明多个AutoCloseable资源,按声明顺序创建、逆序关闭,确保依赖安全;资源须独立声明,不支持赋值或复用变量;关闭异常作为suppressed exceptions附加到主异常。

在 Java 中,try 括号内声明多个需要自动释放的资源对象,使用的是 try-with-resources 语句,且这些资源必须实现 AutoCloseable 接口(如 InputStream、OutputStream、Connection、Statement 等)。
语法:用分号分隔多个资源声明
多个资源写在 try 后的圆括号中,用分号 ; 隔开,**不能用逗号**。JVM 会按声明顺序创建资源,再按**相反顺序**自动调用 close() 方法(即后声明的先关闭),确保依赖关系安全(例如流应晚于其底层通道关闭)。
示例:
try (FileInputStream fis = new FileInputStream("a.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"))) {
// 使用资源
} // 自动关闭:osw → bis → fis(逆序)
资源必须是独立声明的局部变量
每个资源必须是带类型、变量名和初始化表达式的完整声明;不支持赋值语句或已有变量复用。
- ✅ 正确:
BufferedReader br = new BufferedReader(...) - ❌ 错误:
br = new BufferedReader(...)(缺少类型和声明) - ❌ 错误:
BufferedReader br1, br2 = ...(不支持多变量声明)
异常处理与关闭顺序保障
即使某个 close() 抛出异常,JVM 仍会继续关闭其余资源。若 try 块和多个 close() 都抛异常,只有 try 块的异常被抛出,其他关闭异常会作为 suppressed exceptions 附加到主异常中,可通过 exception.getSuppressed() 获取。
注意:资源之间有依赖时,声明顺序很重要
比如包装流依赖底层流,必须先声明底层流,再声明包装流,才能保证关闭时不抛 IOException(否则可能关闭底层流后,包装流再 close 就失效或报错)。
- ✅ 推荐:
new FileInputStream()→new BufferedInputStream(fis) - ⚠️ 危险:
new BufferedInputStream(new FileInputStream())写成单个表达式 —— 底层流无法单独管理,关闭时机不可控

















