Java传统IO资源关闭的正确做法是使用try-with-resources(JDK7+)或try-catch-finally,核心是确保close()在finally中执行且二次捕获异常,避免资源泄漏和异常掩盖。

Java 传统 IO 流关闭资源时,用 try-catch 手动关闭容易出错,核心问题在于:如果流创建失败或关闭过程中抛异常,可能导致资源未释放或异常被掩盖。正确做法不是只靠普通 try-catch,而是要结合 try-catch-finally 或更推荐的 try-with-resources(JDK 7+)。下面分情况说明。
手动关闭:用 try-catch-finally 确保 close() 执行
在 JDK 7 之前常用此方式。关键点是把 close() 放在 finally 块中,并对 close() 再次 try-catch —— 因为它本身可能抛 IOException。
- 先在 try 块中创建流、读写数据
- 在 finally 块中判断流是否为 null,再调用 close()
- close() 外层再套 try-catch,避免因关闭异常影响主逻辑异常传播
示例:
InputStream is = null;
try {
is = new FileInputStream("data.txt");
int b;
while ((b = is.read()) != -1) {
System.out.print((char) b);
}
} catch (IOException e) {
System.err.println("读取失败:" + e.getMessage());
} finally {
if (is != null) {
try {
is.close(); // 关闭也可能抛 IOException
} catch (IOException e) {
System.err.println("关闭流失败:" + e.getMessage());
}
}
}
推荐写法:用 try-with-resources 自动关闭
这是 JDK 7 引入的语法糖,要求资源类实现 AutoCloseable 接口(所有标准 IO 流都满足)。JVM 会在 try 块结束时自动调用 close(),无需手动写 finally,也支持多资源声明。
立即学习“Java免费学习笔记(深入)”;
- 资源声明写在 try 后的括号里,用分号隔开
- 即使 try 中抛异常,资源仍会被关闭;若 try 和 close 都抛异常,后者会作为抑制异常(suppressed)附加到主异常上
- 不用判空,也不用手动处理 close 的异常(除非你要显式处理)
示例:
try (FileInputStream is = new FileInputStream("data.txt");
BufferedInputStream bis = new BufferedInputStream(is)) {
int b;
while ((b = bis.read()) != -1) {
System.out.print((char) b);
}
} catch (IOException e) {
System.err.println("IO 操作失败:" + e.getMessage());
}
// bis 和 is 会按声明逆序自动关闭,无需任何 finally 或 close() 调用
常见误区提醒
很多人以为只在 try 里关流就够了,或者 catch 里关流,其实都不安全:
- ❌ 在 try 块末尾直接 close():如果前面读写已抛异常,close() 就不会执行
- ❌ 在 catch 块里 close():如果异常发生在 close() 之前,流可能没被关;而且如果 catch 里再抛异常,原异常就丢失了
- ❌ 忘记对 close() 做 try-catch:它可能抛 IOException,导致 finally 块异常中断
- ✅ 正确思路:关闭动作必须在 finally 或由 JVM 保证执行,且关闭异常不应掩盖主异常
补充:自定义资源类如何支持 try-with-resources
如果你写了自定义流或资源类,只需让其 实现 AutoCloseable 接口,并重写 close() 方法即可:
public class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("资源已释放");
}
}
// 使用:
try (MyResource r = new MyResource()) {
// ...
}


















