java序列化多个对象到同一文件需复用单个objectoutputstream实例并顺序调用writeobject(),否则因重复流头抛streamcorruptedexception;反序列化须严格按写入次数调用readobject(),建议用try-catch(eofexception)循环读取或封装为集合整体序列化。

Java 中序列化多个对象到同一个文件,核心是复用同一个 ObjectOutputStream 实例,按顺序多次调用 writeObject()。不能为每个对象新建流,否则会因流头重复导致反序列化失败。
必须用同一个 ObjectOutputStream 写多个对象
每次 new ObjectOutputStream(fileStream) 都会在文件开头写入一个流标识头(stream header)。第二次写入时,这个头会覆盖或冲突,后续读取会抛 StreamCorruptedException。
正确做法是:只创建一次 ObjectOutputStream,然后连续写入多个对象:
- 用
FileOutputStream("data.ser")打开文件输出流 - 用该流构造唯一的
ObjectOutputStream - 反复调用
oos.writeObject(obj),支持任意数量、任意类型(只要都可序列化) - 最后统一
close()或flush()
反序列化时必须严格按写入顺序和次数读取
ObjectInputStream 不会自动识别“有多少个对象”,它只是按字节流顺序逐个解析。你写了几个,就必须调用几次 readObject()。
- 读取次数少于写入次数:后续对象被跳过,数据残留但无法访问
- 读取次数多于写入次数:触发
EOFException(文件结束异常) - 建议用循环 +
try-catch(EOFException)安全读取全部,或提前存入对象总数作为首项
注意 transient 和引用对象的连带序列化
每个被写入的对象,其所有非 transient、非 static 字段都会参与序列化。如果字段是另一个自定义类的实例,该类也必须实现 Serializable,否则抛 NotSerializableException。
- 例如:
Person类里有Address addr字段 →Address也得实现Serializable - 标记为
transient的字段(如密码、缓存)会被跳过,不写入文件 - 静态字段永远不参与序列化,无论是否加
transient
推荐封装成集合再序列化(更简洁安全)
如果多个对象逻辑上属于一组(如一批用户、几条日志),更稳妥的做法是先放进 ArrayList 或 LinkedList,再整体序列化单个集合对象。
- 避免手动计数和顺序错位风险
- 反序列化后直接得到完整列表,无需循环重建
- 集合本身可序列化,内部元素也需满足序列化要求
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











