java中try-with-resources可自动关闭fileinputstream和fileoutputstream,因其实现了autocloseable接口,但资源必须在try括号内直接声明初始化,否则不触发自动关闭;多资源用分号分隔,按声明逆序关闭,且无论是否异常均确保已初始化资源被关闭。

Java 中 try-with-resources 能自动关闭 FileInputStream 和 FileOutputStream,前提是它们必须实现 AutoCloseable 接口(而这两个类确实实现了),并且在 try 语句的括号中正确声明。
资源必须在 try 括号中声明
只有在 try 后面的圆括号里直接初始化的资源,才会被自动调用 close()。如果先在外面 new 出来再传进去,就不会触发自动关闭。
- ✅ 正确写法:
try (FileInputStream fis = new FileInputStream("in.txt");
FileOutputStream fos = new FileOutputStream("out.txt")) {
// 读写操作
}
- ❌ 错误写法(不会自动关闭):
FileInputStream fis = new FileInputStream("in.txt");
try (fis) { ... } // 编译报错:fis 不是 final 或 effectively final 的局部变量
多个资源用分号分隔,按声明逆序关闭
try-with-resources 支持同时管理多个资源,它们用分号隔开。JVM 会按**声明的相反顺序**调用 close(),比如先声明 fis,再声明 fos,那么关闭时先关 fos,再关 fis —— 这对依赖关系很重要(例如输出流应晚于输入流关闭)。
- 资源关闭不依赖于是否发生异常:无论正常执行完还是中途抛出异常,所有已成功初始化的资源都会被关闭
- 如果某个
close()抛异常,且 try 块中已有异常,那么 close 异常会被抑制(suppressed),主异常仍被抛出
确保构造过程不出异常,否则未初始化的资源不会被关闭
资源初始化(即 new 表达式)如果抛出异常,该资源对象没创建成功,自然也不会进入关闭流程。但已成功初始化的前面资源仍会正常关闭。
- 例如:
try (A a = new A(); B b = new B()),若new B()失败,a仍会被关闭 - 所以文件路径错误、权限不足等导致构造失败时,只需关注异常本身,无需手动清理
替代方案:嵌套 try 或 finally 不再推荐
在 try-with-resources 出现前,常用 try-catch-finally 手动 close,容易遗漏或出错(比如 close 本身抛异常掩盖主异常)。现在完全没必要这么写:
- 不用再写
fis.close()或fos.close() - 也不用担心 close 放在 finally 里因异常吞掉原始异常的问题
- 代码更简洁,资源生命周期清晰可控
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











