try-with-resources通过在try括号内声明autocloseable资源,由编译器自动逆序关闭,确保主异常不被覆盖、资源不泄漏;多资源用分号分隔,close()仅做释放操作且支持抑制异常获取。

用 try-with-resources 优化异常处理流程,核心是把资源生命周期交给编译器管理,让关闭逻辑自动发生、不干扰主异常、也不依赖人工判断。它不是“加个语法糖”,而是重构了资源与异常的协作关系。
资源声明必须在 try 括号内完成
资源变量不能提前声明,也不能复用已有变量。必须在 try 后的圆括号中直接初始化,且类型需实现 AutoCloseable 或其子接口 Closeable。
- ✅ 正确写法:
try (BufferedReader br = new BufferedReader(new FileReader("a.txt"))) { ... } - ❌ 错误写法:
BufferedReader br; try (br = new BufferedReader(...)) { ... }(编译报错) - 常见可用资源:FileInputStream、Connection、PreparedStatement、Scanner、SocketChannel 等
多资源按逆序自动关闭,避免依赖冲突
多个资源用分号分隔,JVM 按声明的**相反顺序**调用 close(),即“后开先关”。这对有依赖关系的资源(如流套接流)很关键。
- 例如:
try (FileInputStream fis = ...; BufferedReader br = new BufferedReader(new InputStreamReader(fis))) { ... } - 关闭时先调
br.close(),再调fis.close(),防止 br 关闭时还依赖 fis - 每个资源的 close() 都独立执行,前一个失败不影响后续关闭
异常处理更干净:主异常优先,关闭异常不丢失
如果 try 块抛异常,同时某个 close() 也抛异常,JVM 会把 close 异常作为“被抑制异常”附加到主异常上,而不是覆盖它。
- 主异常照常向上抛出,可通过
e.getSuppressed()获取所有被抑制的异常 - 日常开发中若不需深挖,可忽略抑制异常——资源已尝试关闭,日志和 IDE 通常会一并显示
- 避免在 close() 方法里写业务逻辑,只做释放操作(如关连接、清缓存、解锁),保证幂等性
自定义资源类只需实现 AutoCloseable
不是 JDK 自带的类也能用 try-with-resources,只要实现接口并提供 clean 的 close() 方法即可。
- 示例:
class MyDatabaseConnection implements AutoCloseable { public void close() throws SQLException { /* 执行 disconnect */ } } - close() 可声明抛出具体异常(如 IOException、SQLException),编译器会据此生成适配的 finally 逻辑
- 不要在 try-with-resources 块内手动调用 close(),否则可能重复关闭引发 IllegalStateException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











