java中应优先用try-with-resources自动管理资源,因其自动判空、逆序关闭、异常不掩盖;若必须手写finally,则须严格判空、分捕close异常、按依赖逆序关闭。

Java 中传统的 try-catch-finally 关闭资源方式容易出错,核心问题不是“没写 finally”,而是手动管理时判空遗漏、异常吞并、顺序混乱、多资源冗余。优化方向明确:能用 try-with-resources 就不用手写 finally;若必须手写,则聚焦三点——判空、分捕、逆序。
优先改用 try-with-resources
只要资源类实现 AutoCloseable(如 FileInputStream、BufferedReader、Connection、Socket、阿里云 SDK 的 Client),就应直接替换:
- 自动判空:即使构造失败为
null,也不会触发NullPointerException - 自动按声明逆序关闭:后声明的先关,对包装流(如
BufferedReader套FileInputStream)天然安全 - 异常不掩盖:try 块抛出的主异常保留,close 失败作为 suppressed exception 附在主异常上,调用
e.getSuppressed()可查
手写 finally 时必须判空 + 分捕
某些场景无法用 try-with-resources(如资源由工厂创建、需复用、或非 AutoCloseable 类型),此时 finally 必须严格遵循:
- 每个资源变量声明为
null,关闭前统一加if (resource != null) - 每个
close()单独套try-catch,且不throw——只记录日志或忽略(低风险场景) - 避免把多个 close 塞进同一个 try 块,否则一个失败会中断后续关闭
多资源关闭要按打开逆序,逐个处理
比如同时用到数据库连接、语句、结果集,或文件流+缓冲流+网络 Socket:
- 关闭顺序必须是:ResultSet → Statement → Connection,或 BufferedReader → FileInputStream,或 Socket → InputStream/OutputStream
- 不能只关第一个就结束;也不能靠 catch 吞掉异常后跳过后续关闭
- 每个资源独立判空、独立 try-catch,彼此无依赖
关键资源别只靠 finally,要主动兜底
finally 并非绝对可靠——遇到 System.exit()、JVM 崩溃、线程被强制终止等情况会跳过。对事务提交、锁释放、关键连接等:
- 在 try 块末尾、业务逻辑确认成功后,主动调用
commit()或unlock() - 配合超时机制(如
Lock.tryLock(timeout, unit))防死锁卡住 - 避免在 finally 里写
return或抛新异常,防止覆盖主流程返回值或异常
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











