✅ ObjectInputStream 和 ObjectOutputStream 自 Java 7 起实现 AutoCloseable,可在 try-with-resources 中自动关闭,但必须与底层流(如 FileInputStream/OutputStream)一同声明于括号内,确保整条流链被统一管理并按逆序安全关闭。

Java 中 try-with-resources 能自动关闭 ObjectInputStream 和 ObjectOutputStream,前提是它们被正确声明在 try 括号内,且所用的底层流也支持自动关闭。
确认类本身支持 AutoCloseable
ObjectInputStream 和 ObjectOutputStream 从 Java 7 起就实现了 AutoCloseable 接口,可以直接用于 try-with-resources。但要注意:它们只是装饰器,真正释放资源依赖于底层流(如 FileInputStream 或 FileOutputStream)是否也被纳入管理。
- ✅
ObjectInputStream和ObjectOutputStream本身可自动 close() - ✅ 它们的构造参数必须是已实现
AutoCloseable的流(如FileInputStream、ByteArrayInputStream等) - ⚠️ 如果传入的是未实现
AutoCloseable的自定义流(或旧版 Scanner),则整个链无法保证安全释放
正确写法:嵌套流必须统一由 try-with-resources 管理
不能只声明 ObjectInputStream,而让底层 FileInputStream 在外部创建——那样底层流不会被自动关闭。
- ❌ 错误:底层流在 try 外声明
FileInputStream fis = new FileInputStream("data.ser");
try (ObjectInputStream ois = new ObjectInputStream(fis)) { ... }
立即学习“Java免费学习笔记(深入)”;
- ✅ 正确:所有流都在括号内声明,按依赖顺序逆序关闭(外层先关,内层后关)
try (FileInputStream fis = new FileInputStream("data.ser");
ObjectInputStream ois = new ObjectInputStream(fis)) {
MyObj obj = (MyObj) ois.readObject();
}
序列化写入同理,注意 OutputStream 链的完整性
写对象时,ObjectOutputStream 同样需要包裹一个可关闭的输出流。常见组合是 FileOutputStream → ObjectOutputStream。
- 关闭顺序是:先关
ObjectOutputStream,再关FileOutputStream(声明顺序相反) - 调用
ObjectOutputStream.close()会自动触发底层流的close(),但前提是底层流也在 try-with-resources 中——否则它根本不会被关
try (FileOutputStream fos = new FileOutputStream("data.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(new MyObj());
}
异常处理与抑制机制要留意
序列化/反序列化过程容易抛出 IOException 或 ClassNotFoundException;如果 close() 也失败(比如磁盘满导致 FileOutputStream.close() 报错),该异常会被抑制,不会掩盖主异常。
- 主异常仍被抛出,可通过
e.getSuppressed()查看被抑制的 close 异常 - 建议在开发期加日志或断点验证:两个流是否都执行了
close() - 不要在
ObjectOutputStream的close()里做耗时操作(如网络同步),它应轻量、快速


















