最可靠的方式是用 try-with-resources,它能确保流在作用域结束时自动关闭,无论是否发生异常;资源须在 try 小括号内声明,多个用分号隔开,关闭顺序与声明相反,嵌套流应统一纳入其中,手动关闭仅作兜底。

最可靠的方式是用 try-with-resources,它能确保流在作用域结束时自动关闭,无论是否发生异常。这是 Java 7+ 的标准做法,也是防止资源泄漏的首选方案。
优先使用 try-with-resources
只要流实现了 AutoCloseable(如 FileInputStream、BufferedReader、ObjectInputStream 等),就应直接在 try 括号中声明并初始化:
- 资源必须在
try小括号内创建,写在外面不会触发自动关闭 - 多个资源用分号隔开,关闭顺序与声明顺序相反(后声明的先关)
- 即使
try块中抛出异常,所有资源仍会依次调用close() -
close()自身若抛异常,会被抑制(suppressed),主异常仍可捕获
嵌套流要各自独立关闭
像 FileInputStream → ObjectInputStream 这类包装关系,不能只关外层——如果外层 close() 抛异常,内层就可能跳过关闭,导致句柄泄漏:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 正确做法:全部放进同一个
try-with-resources中,让 JVM 自动处理关闭顺序 - 若因兼容旧版本无法用 try-with-resources,则每个流都需单独
try-catch关闭,不能共用一个finally块 - 避免写成:
if (fis != null) fis.close(); if (ois != null) ois.close();——中间出错会导致后续跳过
全局或长期持有的流需额外管理
当流生命周期超出单个方法(如配置监听器、日志收集器),不能依赖局部作用域自动释放:
- 用
AtomicReference<fileinputstream></fileinputstream>管理引用,保证线程安全 - 提供显式的
closeStream()方法,并在业务逻辑中主动调用 - 注册
ShutdownHook仅作兜底:执行非阻塞关闭,且忽略所有IOException,不用于弥补设计缺陷
手动关闭仅作为兜底或兼容手段
在无法使用 try-with-resources 的场景(如 Java 6 或某些特殊框架限制),手动关闭必须满足:
- 资源变量声明在
try外,但初始化在try内 -
finally中判空后关闭,且每个close()单独包裹try-catch - 不建议用工具类如
IOUtils.closeQuietly()隐藏问题,生产环境应记录关闭失败日志
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










