externalizable 彻底接管序列化:需显式实现接口、提供public无参构造器、重写writeexternal与readexternal方法;字段完全手动控制,读写顺序类型必须严格一致,无反射开销,性能更高但要求严格。

用 Externalizable 替代 Serializable,不是“微调序列化”,而是彻底接管整个过程:字段选不选、怎么写、怎么读、是否兼容旧版本,全由你定。它省掉反射、跳过元数据、不存无用字段,自然更轻更快——但前提是写对。
必须满足的三个硬性条件
缺一不可,否则运行时直接报错:
- 类必须 显式 implements Externalizable(不能只实现 Serializable)
- 必须提供一个 public 无参构造器(反序列化时 JVM 会先调它创建空对象,再进 readExternal)
- 必须重写 writeExternal(ObjectOutput out) 和 readExternal(ObjectInput in) 两个方法
字段完全由你决定写不写、怎么写
Externalizable 不会自动处理任何字段——哪怕 public、非 transient、甚至父类字段,统统不碰。你写哪几个,才存哪几个;顺序、类型、编码方式,全在你手。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 只写真正需要持久化的字段,比如跳过
cacheMap、isProcessing、getFullName()计算结果 - 可主动加轻量元信息:开头写
out.writeInt(2)表示版本号,后续按版本分支读取逻辑 - 敏感字段如
passwordHash,只要不调out.writeXXX(),就绝不会出现在字节流里——transient在这里无效也不需加
读写顺序和类型必须严格镜像
readExternal 必须和 writeExternal 的调用顺序、参数类型、调用次数完全一致。错一位、混一个类型,就会抛 StreamCorruptedException 或类型转换异常。
- 例如 writeExternal 中写了:
out.writeInt(id); out.writeUTF(name); out.writeBoolean(active); - 那么 readExternal 就必须严格对应:
id = in.readInt(); name = in.readUTF(); active = in.readBoolean(); - 如果加了版本号,读时要先
int version = in.readInt();,再根据 version 判断是否读新增字段、是否跳过已废弃字段
与 Serializable 的本质区别
这不是“增强版 Serializable”,而是另一套机制:
-
Serializable 自动保存所有非 transient 字段,靠
serialVersionUID控制兼容性,有默认字段描述和类型信息开销 - Externalizable 没有默认行为:不递归处理父类字段、不识别 transient、不调用 defaultWriteObject/defaultReadObject、也没有 writeObject/readObject 钩子
- 性能提升来自“精准控制”:少写一个字段,就少占若干字节;少一次反射,就少一次运行时开销;少一层嵌套遍历,就少一分不确定性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










