应使用 try-with-resources 替代 finally 关闭资源,要求资源实现 AutoCloseable 接口,在 try() 中声明并初始化,JVM 逆序自动关闭;支持异常抑制机制,资源作用域限于 try 块内,null 资源不可直接声明于括号中。

用 try-with-resources 替代传统 finally 关闭,核心是让资源实现 AutoCloseable 接口,并在 try 后的括号中声明资源。JVM 会自动调用 close(),无需手动写 finally 块。
资源必须实现 AutoCloseable
只有实现了 AutoCloseable(或其子接口 Closeable)的类才能用于 try-with-resources。常见如 FileInputStream、BufferedReader、Connection、PreparedStatement 等都已实现。
- 自定义资源类只需重写 close() 方法并声明抛出 Exception 或更具体的异常
- 如果 close() 可能抛异常,建议声明为 throws Exception,让上层处理或由 try-with-resources 自动抑制
基本语法:把资源声明写在 try( ) 里
资源在小括号中初始化,多个资源用分号隔开,JVM 按声明**逆序**自动关闭(后声明的先关),且无论是否发生异常都会执行关闭。
try (FileInputStream fis = new FileInputStream("a.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
String line = br.readLine();
System.out.println(line);
} // ← 这里 br 和 fis 自动关闭,无需 finally
- 资源变量作用域仅限于 try 块内,不能在外部访问
- 每个资源语句末尾要加分号(除了最后一个)
- 如果资源创建失败(如文件不存在),try 块不执行,但已成功创建的资源仍会被关闭
异常处理:自动抑制(suppressed)机制
若 try 块抛异常,且 close() 也抛异常,后者不会覆盖主异常,而是作为 suppressed exception 附加到主异常上,可通过 getSuppressed() 获取。
立即学习“Java免费学习笔记(深入)”;
- 主异常仍正常抛出,程序行为与原来一致
- 调试时可用 e.printStackTrace() 查看被抑制的异常(JDK7+ 默认显示)
- 若需显式处理 close 异常,可重写 close() 并记录日志,但一般不建议 throw
兼容旧代码:资源可为 null,但需确保构造不抛 NPE
如果资源可能为 null,try-with-resources 不会调用 close(),也不会报错。但注意:null 资源本身不能出现在括号中(编译不通过),应确保初始化成功或提前判空。
- 错误写法:
try (BufferedReader br = maybeNullReader) { ... }(编译失败) - 正确做法:确保表达式结果非 null,或在外层判空后才进入 try-with-resources
- 若资源获取逻辑复杂,可封装成方法返回 AutoCloseable 实例,保持 try 括号内简洁


















