transient 字段默认不参与序列化,但可通过自定义 private writeobject 和 readobject 方法实现手动序列化与反序列化;需先调用 defaultwriteobject/defaultreadobject 处理非 transient 字段,再按相同顺序读写 transient 字段,且类必须实现 serializable 接口。

被 transient 修饰的字段默认不会参与 Java 默认序列化过程,但你可以通过手动实现 writeObject 和 readObject 方法,在序列化/反序列化时自定义它的处理逻辑。
在类中声明 private writeObject 方法
Java 序列化机制会自动查找类中是否定义了私有的 writeObject 方法(签名必须严格匹配),如果存在,就调用它代替默认序列化流程。注意:该方法不能是 static 或 final,且必须是 private void writeObject(ObjectOutputStream out) throws IOException。
- 先调用
out.defaultWriteObject()执行默认序列化(处理非 transient 字段) - 再手动写入 transient 字段的值(比如调用
out.writeInt()、out.writeUTF()等) - 顺序要和
readObject中读取的顺序严格一致
配套实现 readObject 进行反序列化还原
仅写 writeObject 是不够的——反序列化时必须有对应的 readObject 来恢复 transient 字段,否则字段保持默认值(如 null、0、false)。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 同样为
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException - 先调用
in.defaultReadObject()恢复非 transient 字段 - 再按相同顺序读取你之前写入的 transient 数据(如
in.readInt()、in.readUTF())并赋值给对应字段
注意字段可访问性与安全性
即使字段是 private,writeObject/readObject 也能直接访问它,这是 JVM 序列化机制的特例。但要注意:
- 不要在这些方法里暴露敏感信息(比如把密码明文写入流)
- 若 transient 字段本身不可序列化(如含非 serializable 对象),需自行转换为可序列化形式(如转成 JSON 字符串或 byte[])
- 确保类实现了
Serializable接口,否则整个序列化会失败
一个简单示例
假设有个用户类,其中 token 是临时凭证,标记为 transient,但仍希望在序列化时保留其内容:
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeUTF(token != null ? token : "");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
token = in.readUTF();
if (token.isEmpty()) token = null;
}
这样既跳过了默认序列化对 token 的忽略,又保证了数据可逆还原。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










