try-with-resources可自动关闭实现AutoCloseable接口的资源,按声明逆序关闭,支持多资源、Java9变量复用,避免手动close和异常覆盖,比传统finally更简洁安全。

直接在 try 后的括号里声明流对象,JVM 会自动调用 close(),不用写 finally,也不用担心忘记关或重复关。
资源必须实现 AutoCloseable 接口
只有实现了 AutoCloseable(或其子接口 Closeable)的类才能用于 try-with-resources。常见流类如 FileInputStream、BufferedReader、Connection、PreparedStatement 都已实现该接口。
- 自定义类只需实现
close()方法,并声明抛出Exception或具体异常(如IOException)即可 - 不要对非 AutoCloseable 对象强行包装——比如普通 POJO 或未实现该接口的工具类,加了也没用
- Java 9 起支持复用已声明变量:可先创建
FileInputStream fis = new FileInputStream(...),再写try (fis) { ... }
多资源声明与关闭顺序要清楚
多个流可在同一 try 括号中声明,用分号分隔;它们按**声明的逆序**自动关闭——后声明的先关,先声明的后关。
- 例如:
try (InputStream in = ...; OutputStream out = ...),则先关out,再关in - 这种顺序能避免依赖冲突,比如缓冲流依赖底层流,就得先关缓冲流、再关底层流
- 别在 try 块内给资源变量重新赋值,否则原始对象可能无法被正确关闭
异常处理要兼顾主异常和抑制异常
如果 try 块抛异常,且某个资源的 close() 也抛异常,后者不会覆盖前者,而是作为“抑制异常”附加到主异常上。
立即学习“Java免费学习笔记(深入)”;
- 捕获异常后,可用
e.getSuppressed()获取所有被抑制的异常 - 不必在 try-with-resources 中手动调用
close(),否则可能触发重复关闭,导致IOException或IllegalStateException - 资源变量作用域仅限 try 块内,不能在 catch 或 finally 中直接访问
对比传统写法更简洁安全
相比手写 try-catch-finally,try-with-resources 省去 null 判断、嵌套 try-catch 和易遗漏的 close() 调用。
- 编译后它本质是语法糖,会被转成带 finally 的结构,但由编译器保证逻辑完整
- 即使 try 块中发生异常,所有已成功初始化的资源仍会依次尝试关闭
- 代码行数减少约 40%,可读性提升,排查问题时异常堆栈也更干净


















