Java的Object类不提供序列化逻辑,JVM通过运行时实际类型自动实现多态序列化:写入时按真实类(如Dog)完整序列化,反序列化后仍为原类型实例,行为与字段均保留。

Java 的 Object 类本身**不提供序列化与反序列化的实现逻辑**,也不参与多态分发——它只是所有类的根父类,没有 writeObject 或 readObject 这类方法。真正支撑“统一序列化分发 + 多态行为保留”的,是 JVM 序列化机制对 **运行时实际类型(而非引用类型)的自动识别与处理**,配合 Serializable 接口的契约约定。
多态性如何在序列化中自然生效
当你用 ObjectOutputStream.writeObject(obj) 写入一个对象时,JVM 不看变量声明类型(比如 Animal a = new Dog();),而是检查 obj 在堆中的**真实类(Dog.class)**。只要该类(及其可访问的超类字段)实现了 Serializable,整个对象图就会按实际类型完整序列化——包括子类独有的字段、重写的 toString()、compareTo() 等行为元信息也会被记录。
反序列化时,ObjectInputStream.readObject() 读出的仍是 Dog 实例,不是 Animal。因此调用 a.bark()(假设 Dog 有该方法)不会失败,多态行为完全保留。
- 无需在
Object中写任何分发代码 - 无需显式
instanceof判断或 switch 分支 - 只要子类可序列化,JVM 自动按实际类型走对应逻辑
关键前提:可序列化的继承链必须完整
如果父类(如 Animal)未实现 Serializable,其字段在序列化时会被跳过;反序列化后,这些字段值为默认值(null、0、false),且父类无参构造器会被调用。这会破坏状态一致性,但**不影响多态方法调用**——因为方法属于类定义,不依赖字段值。
立即学习“Java免费学习笔记(深入)”;
- 推荐所有参与序列化的类(含父类)都实现
Serializable - 若父类不可改,子类可通过
writeObject/readObject手动保存/恢复父类字段
serialVersionUID 是多态兼容的“版本锚点”
当类结构变化(如新增字段、修改方法签名),JVM 靠 serialVersionUID 判断能否安全反序列化。这个 UID 是类级别的,与多态无关,但它保障了“相同语义的子类”能跨版本重建——比如 Dog v2.0 反序列化 Dog v1.0 的字节流,仍能正确还原为 Dog 实例并执行全部多态方法。
- 显式声明
private static final long serialVersionUID = 1L;避免编译器自动生成导致版本不匹配 - 仅当语义变更(如字段语义改变、方法行为重构)才需更新 UID
你不需要、也不应该在 Object 层做分发
Object 类没有序列化能力,也不该承担分发职责。真正的“统一入口”是:
-
ObjectOutputStream.writeObject()—— 接收任意Object,内部按实际类型路由 -
ObjectInputStream.readObject()—— 返回Object,由调用方按需强转或使用多态接口
这种设计让业务代码保持简洁:List<Animal> animals = ...; oos.writeObject(animals); —— 无论列表里是 Dog、Cat 还是 Bird,序列化过程全自动,反序列化后仍保持各自类型和行为。


















