Java 7 的 try-with-resources 能自动关闭 AutoCloseable 资源,按声明逆序调用 close(),支持多资源并列声明、异常抑制机制及自定义资源实现;示例涵盖文件读取、复制及日志工具类封装。

Java 7 引入的 try-with-resources 是处理 IO 流最简洁安全的方式,它能自动关闭实现了 AutoCloseable 接口的资源(如 InputStream、OutputStream、Reader、Writer 等),避免手动调用 close() 和冗长的 finally 块。
基本写法:在 try 后括号中声明资源
资源必须是 final 或等效 final(即声明后不重新赋值),且类型需实现 AutoCloseable。JVM 会在 try 块结束(无论正常还是异常退出)时按声明逆序自动调用 close()。
示例:读取文件内容
try (FileInputStream fis = new FileInputStream("data.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
InputStreamReader isr = new InputStreamReader(bis, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(isr)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
上面四层流会按 reader → isr → bis → fis 顺序自动关闭,无需任何 close() 调用。
立即学习“Java免费学习笔记(深入)”;
多个资源可并列声明,用分号分隔
同一 try 括号内可声明多个资源,彼此独立,关闭顺序与声明顺序相反。
- 适合需要同时打开输入和输出流的场景(如复制文件)
- 每个资源单独声明,不嵌套构造也可(但推荐组合提升性能)
- 任一资源初始化失败,已成功创建的资源仍会被自动关闭
示例:文件复制(带异常传播)
try (InputStream in = Files.newInputStream(Paths.get("src.txt"));
OutputStream out = Files.newOutputStream(Paths.get("dst.txt"))) {
in.transferTo(out); // Java 9+ 支持
} catch (IOException e) {
// 所有已打开的流已关闭,直接处理异常即可
throw new RuntimeException("复制失败", e);
}
自定义资源类也要实现 AutoCloseable
如果你封装了带底层流的工具类(比如一个日志写入器),只要让它实现 AutoCloseable 并重写 close() 方法,就能用于 try-with-resources。
-
close()方法应幂等:多次调用不抛异常、不重复操作 - 内部持有的流应在
close()中统一关闭 - 若关闭过程可能抛出异常,建议用
try-catch捕获并记录,避免干扰主流程
注意 suppressed exception(被抑制的异常)
当 try 块抛出异常,且 close() 也抛出异常时,后者不会覆盖前者,而是作为“被抑制异常”附加到主异常上。可通过 getSuppressed() 获取。
- 通常无需主动处理,日志框架或调试器会显示 suppressed 异常
- 如需显式检查,可在 catch 块中遍历
e.getSuppressed() - 这机制确保主错误不被关闭失败掩盖,比传统 finally 更健壮


















