如何使用 ObjectOutputStream 将内存中的集合对象持久化存储

风萱君_2184

风萱君_2184

2026-04-08

279人浏览

原创

objectoutputstream序列化集合前须确保所有元素可序列化,否则运行时抛notserializableexception;必须用fileoutputstream包装并用try-with-resources关闭;反序列化需类版本与serialversionuid严格匹配。

如何使用 objectoutputstream 将内存中的集合对象持久化存储

ObjectOutputStream 序列化集合前必须确保所有元素可序列化

Java 的 ObjectOutputStream 不会自动检查集合内对象是否满足序列化要求,运行时抛出 java.io.NotSerializableException 才暴露问题。常见踩坑点是集合里混入了 ArrayList 但含 Thread、Socket、自定义类未实现 Serializable 接口,或用了 HashMap 但 key/value 中有非序列化类型。

实操建议:

  • 所有待存对象(包括集合自身、元素、嵌套对象)都必须实现 Serializable 接口,哪怕空接口也要显式声明
  • 对第三方类无法修改源码的情况,用 transient 排除字段,或封装为可序列化包装类
  • 使用 IDE 的「Find Usages」功能快速扫描集合元素类型,避免漏掉深层依赖

写入文件时必须配合 FileOutputStream 正确构造 ObjectOutputStream

直接 new ObjectOutputStream 会报编译错误,它没有无参构造器,且必须包裹一个底层输出流。新手常误写成 new ObjectOutputStream(new File("data.bin")) —— 这根本不能编译,因为 File 不是 OutputStream 子类。

正确写法示例:

try (FileOutputStream fos = new FileOutputStream("data.bin");
     ObjectOutputStream oos = new ObjectOutputStream(fos)) {
    oos.writeObject(myList); // myList 是 ArrayList<user> 等可序列化集合
}</user>

注意:

  • 必须按 FileOutputStream → ObjectOutputStream 顺序嵌套,反过来会编译失败
  • 务必用 try-with-resources 自动关闭,否则可能写入不完整(头部信息缺失),后续反序列化直接抛 StreamCorruptedException
  • 不要在同一个 ObjectOutputStream 实例上多次 writeObject 同一对象引用——默认开启对象引用跟踪,第二次只写引用标记,不是完整数据

反序列化时 ClassLoader 和类版本必须严格匹配

用 ObjectInputStream 读取后出现 InvalidClassException: local class incompatible,多数是因为序列化后修改了类结构(如增删字段、改访问修饰符),或运行环境加载了不同版本的类(比如本地开发版 vs 服务器 jar 包)。

关键控制点:

  • 手动声明 private static final long serialVersionUID = 1L;,避免 JVM 自动生成导致微小变更就失效
  • 反序列化代码和序列化时必须使用**同一份 class 文件**,IDE 编译输出路径、Maven 依赖版本、JAR 包内容都要一致
  • 如果集合元素是内部类,必须是 static 的,否则隐含持有外部类引用,而外部类可能不可序列化

替代方案:什么时候不该用 ObjectOutputStream

序列化二进制格式不具备跨语言、跨版本、可读性等能力,生产环境存集合优先考虑 JSON 或数据库。只有当明确需要 Java 原生对象图深度拷贝、且部署环境完全可控时,才用 ObjectOutputStream。

典型不适用场景:

  • 集合要被 Python/Go 等其他语言读取 → 改用 ObjectMapper.writeValueAsBytes() 输出 JSON
  • 数据需长期存储(超过 1 年)→ 类结构演进必然发生,二进制格式极易失效
  • 集合含敏感字段(如密码)→ ObjectOutputStream 不加密,明文落盘风险高,应先加密再写入

真正稳定的持久化从来不是靠序列化机制本身,而是靠对类演化边界的清醒预判和主动约束。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10677

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7802

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6792

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1144

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

948

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1396

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2809

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20111

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1235

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.7万人学习