externalizable 是 java 中完全自定义序列化的接口,需实现 writeexternal 和 readexternal 方法并提供 public 无参构造器;不自动保存任何字段,读写顺序与类型必须严格一致,适用于需精细控制序列化格式的场景。

Externalizable 是 Java 中用于完全自定义序列化行为的接口,它比 Serializable 更底层、更灵活——你放弃默认序列化机制,自己决定哪些字段写入、如何写入、如何读回。
实现 Externalizable 的基本要求
类必须实现 Externalizable 接口,并提供一个 public 的无参构造器(反序列化时会调用它)。接口只定义两个方法:
-
writeExternal(ObjectOutput out):手动把对象状态写入输出流 -
readExternal(ObjectInput in):手动从输入流读取数据并恢复对象状态
注意:不会自动保存任何字段,包括父类字段或 transient 字段——全靠你在两个方法里显式处理。
写入时只写你需要的字段
在 writeExternal 中,按你希望的顺序调用 out.writeXXX() 方法。例如:
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeUTF(name);
out.writeBoolean(active);
// 不写 createTime,也不调用 super.writeExternal()
}
你可以跳过敏感字段、计算字段、或兼容旧版本时被移除的字段。也可以添加版本标识、校验码等自定义元数据。
读取时严格按写入顺序还原
readExternal 必须与 writeExternal 的写入顺序、类型、数量完全一致,否则抛 StreamCorruptedException 或类型不匹配异常。例如:
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
id = in.readInt(); // 必须先读 int
name = in.readUTF(); // 再读 String
active = in.readBoolean(); // 最后读 boolean
}
如果类结构升级(比如新增字段),老数据反序列化时会因读多/读少失败。常见做法是在开头写入版本号,根据版本分支读取逻辑。
与 Serializable 的关键区别
-
Serializable自动保存非 transient 字段,支持serialVersionUID兼容性控制;Externalizable完全不走这套,连父类字段都不管 -
Externalizable的无参构造器是强制的,且会在反序列化时被调用(可能执行初始化逻辑) - 没有默认的序列化代理机制,也没有
writeObject/readObject那样的钩子方法,一切由你掌控
适合场景:需要极致控制序列化格式(如对接遗留系统)、做压缩/加密、跳过大量临时字段、或实现跨语言兼容的二进制协议。










