Java中try-with-resources可自动关闭实现AutoCloseable的InputStream,需在try括号内直接声明初始化;支持多资源逆序关闭,close异常会被抑制并可通过getSuppressed()获取;自定义流须确保close()幂等且释放内部资源。

Java 中 try-with-resources 能自动关闭 InputStream,前提是该流实现了 AutoCloseable 接口(JDK 7+ 的所有标准输入流都满足)。
必须用 try-with-resources 声明流对象
不能先创建再传入 try 块,必须在 try 后的括号内直接初始化:
- ✅ 正确写法:流在 try 括号中声明并实例化,JVM 保证异常时也调用
close() - ❌ 错误写法:在 try 外 new 流、再放进 try,此时不会被自动管理,可能泄漏
支持多个资源,按声明逆序关闭
可在同一 try 括号中声明多个资源,用分号隔开,关闭顺序与声明顺序相反(后声明的先关):
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 例如:
try (InputStream in = new FileInputStream("a.txt"); OutputStream out = new FileOutputStream("b.txt")) { ... } - 即使
in.close()抛异常,out.close()仍会执行(且前者异常会被抑制,除非没有其他异常)
捕获异常时注意 suppressed exception(被抑制的异常)
如果 try 块抛出异常,且 close() 也抛异常,后者会被“抑制”,可通过 Throwable.getSuppressed() 获取:
立即学习“Java免费学习笔记(深入)”;
- 通常无需手动处理,但调试时可打印:
for (Throwable s : e.getSuppressed()) System.err.println("Suppressed: " + s); - 这避免了因 close 失败而掩盖主逻辑异常的问题
自定义 InputStream 也要实现 AutoCloseable
若你写了子类继承 InputStream,只要没重写 close() 为非 public 或抛受检异常,它就天然支持 try-with-resources:
- 确保
close()方法能安全多次调用(幂等) - 如果内部持有其他资源(如 Socket、FileChannel),应在
close()中一并释放

















