java 7 的 try-with-resources 语句可自动关闭实现 autocloseable 接口的资源,按声明逆序调用 close(),支持异常抑制,比传统 finally 手动关闭更简洁安全。

Java 7 引入的 try-with-resources 语句,能自动管理实现了 AutoCloseable 接口的资源(如 InputStream、OutputStream、Connection 等),彻底避免手写 finally 块关闭流的模板代码,既简洁又安全。
核心前提:资源必须实现 AutoCloseable
只有实现了 java.lang.AutoCloseable 接口的类才能用于 try-with-resources。JDK 中绝大多数 I/O 流、JDBC 资源都已实现该接口(例如 FileInputStream、BufferedReader、PreparedStatement)。
- 自定义资源类只需重写
close()方法,并声明实现AutoCloseable - 注意:
Closeable是AutoCloseable的子接口,所以所有Closeable类天然支持
基本语法:把资源声明在 try 括号里
资源变量需在 try 后的圆括号中声明,用分号分隔;JVM 会在 try 块结束(无论正常还是异常退出)时自动调用其 close() 方法。
try (FileInputStream fis = new FileInputStream("data.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
String line = reader.readLine();
System.out.println(line);
} // ← fis 和 reader 在此处自动 close()
- 资源按声明顺序创建,按**逆序**关闭(后声明的先关闭),适合有依赖关系的场景(如先关 reader 再关 fis)
- 即使 try 块中抛出异常,close() 仍会执行;若 close() 本身也抛异常,会被抑制(suppressed),可通过
Throwable.getSuppressed()获取
处理多个异常:try-with-resources 天然支持异常抑制
当 try 块抛异常,且多个资源的 close() 也抛异常时,主异常保留,其他 close 异常被“抑制”并附加到主异常上。
try (Resource r1 = new Resource(); Resource r2 = new Resource()) {
r1.doSomething(); // 抛出 IOException
} catch (IOException e) {
// e 是主异常
for (Throwable suppressed : e.getSuppressed()) {
System.err.println("Suppressed: " + suppressed);
}
}
- 无需手动捕获 close 异常,避免传统 finally 中嵌套 try-catch 的臃肿写法
- 调试时可通过 IDE 或日志查看被抑制的异常,定位资源清理问题
与传统写法对比:少写 6–10 行,更可靠
传统方式需手动在 finally 中判空并关闭,易遗漏、易 NPE、易掩盖主异常:
// ❌ 容易出错的传统写法
InputStream is = null;
try {
is = new FileInputStream("file.txt");
// ... 使用 is
} finally {
if (is != null) { // 忘记判空?NPE!
is.close(); // close 抛异常?吞掉主异常!
}
}
而 try-with-resources 一行声明,零风险关闭:
// ✅ 简洁安全
try (InputStream is = new FileInputStream("file.txt")) {
// ... 使用 is
} // 自动 close,不抛 NPE,不掩盖异常
- 编译器强制检查资源是否可关闭,IDE 也会高亮提示
- 资源作用域清晰,无法在 try 外误用已关闭的流










