父类实现Serializable接口时,其字段随子类自动序列化;未实现时,父类字段不被保存,反序列化需通过无参构造函数重建,且必须手动处理字段读写。

Java对象序列化时,父类字段的处理方式取决于父类是否实现了Serializable接口。序列化机制会根据这一条件决定如何处理继承层次中的字段。
父类实现Serializable接口
如果父类也实现了Serializable接口,那么整个对象的字段(包括父类和子类)都会自动被序列化机制处理。
这种情况下,所有字段都遵循默认的序列化流程:
- 所有非
transient和非static字段会被自动序列化 - 反序列化时,整个对象图通过标准流程恢复
- 不需要额外操作,构造函数不会被调用
父类未实现Serializable接口
如果父类没有实现Serializable接口,序列化行为会发生变化,这是开发中容易出错的地方。
立即学习“Java免费学习笔记(深入)”;
此时,子类可以正常序列化自己的字段,但父类字段不会被自动保存。反序列化时,这些字段将使用父类无参构造函数重新初始化。
关键点:
- 父类必须提供可访问的无参构造函数(public或protected)
- 父类字段在反序列化后是“新创建”的,不是从流中恢复的
- 若父类无无参构造函数,会抛出
InvalidClassException
控制序列化行为的方法
在父类未实现Serializable的情况下,可以通过以下方式精确控制字段处理:
- 在子类中定义
writeObject和readObject方法手动处理父类字段 - 在
readObject中显式调用父类逻辑来恢复状态 - 使用
ObjectInputStream.defaultReadObject()和ObjectOutputStream.defaultWriteObject()配合自定义逻辑
例如,当需要保留非Serializable父类的字段值时,可以在子类中:
private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeInt(parentField); // 手动写入父类字段 } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); parentField = in.readInt(); // 手动恢复父类字段 }基本上就这些。核心是看父类是否可序列化,决定了字段是自动处理还是需要手动干预。










