Java 7 的 try-with-resources 是编译期语法糖,要求资源实现 AutoCloseable 接口,按声明逆序自动关闭,close 异常被抑制并附加到主异常中。

Java 7 的 try-with-resources 是专为自动管理资源设计的语法,核心目标是让流(如 InputStream、OutputStream、Reader、Writer 等)在使用后**无需手动调用 close() 就能安全关闭**,且无论是否发生异常都生效。
资源必须实现 AutoCloseable 接口
不是所有对象都能放进 try() 括号里。只有实现了 java.lang.AutoCloseable 接口(或其子接口 Closeable)的类才被允许。JDK 中绝大多数标准 I/O 类都已实现:
- FileInputStream / FileOutputStream
- BufferedReader / BufferedWriter
- ObjectInputStream / ObjectOutputStream
- Socket / ServerSocket(部分构造方式下)
- PreparedStatement / ResultSet(JDBC 4.1+)
若自定义类想支持该语法,必须显式声明 implements AutoCloseable,并重写 close() 方法——仅写 close() 方法但不实现接口,编译直接报错。
多资源声明与关闭顺序很重要
多个资源可用分号隔开,它们按**声明逆序关闭**(LIFO):
立即学习“Java免费学习笔记(深入)”;
- 先声明的资源后关闭,后声明的先关闭
- 例如:
try (FileInputStream fis = ...; BufferedInputStream bis = new BufferedInputStream(fis)) { ... }→ 先调bis.close(),再调fis.close() - 这个顺序对装饰器链(如 Buffer → File)至关重要:外层必须先关,否则内层可能丢失缓冲数据
异常处理机制不同于普通 try-catch
try 块抛异常 + close() 抛异常时,行为有明确规则:
- try 块中的异常为主异常,优先抛出
- close() 引发的异常会被“抑制”(suppressed),不会覆盖主异常
- 可通过
exception.getSuppressed()获取被抑制的异常数组 - 即使第一个 close() 失败,后续资源的 close() 仍会执行
常见易错点要避开
实际编码中这几个细节最容易引发隐患:
- 资源变量在 try 括号中声明后默认为 final,不可重新赋值(否则编译报错)
- 如果某资源初始化时就抛异常(如 new FileInputStream 时文件不存在),它不会被关闭,但已成功创建的前置资源会正常关闭
- Java 9 起支持“有效 final”变量引用传入,但 JDK 7/8 不支持,必须在括号内直接 new
- 避免在 close() 方法里做耗时操作(如网络请求、复杂计算),close 应轻量、快速、幂等


















