transient修饰的变量在序列化时被完全跳过,反序列化时设为默认值(基本类型为0/false/0.0,引用类型为null),且该行为与字段类型无关,仅影响序列化流程而不改变其内存语义。

Java 序列化过程中,transient 修饰的变量会被明确跳过,不参与序列化与反序列化流程。它的处理逻辑清晰、统一,且与变量的数据类型无关——无论 int、String、List 还是自定义对象,只要被 transient 修饰,就按同一规则处理。
以下是关键处理方式:
序列化时完全忽略
ObjectOutputStream在默认序列化(即类实现Serializable但未自定义writeObject)时,会遍历所有非静态、非 transient 的实例字段,将其值写入字节流。transient字段直接跳过,不会生成任何对应字节,也不触发其 getter 或任何计算逻辑。-
反序列化时赋予默认值
反序列化重建对象时,JVM 会为每个transient字段分配其类型的默认初始值:- 基本类型 →
0(int/long)、false(boolean)、0.0(double)等 - 引用类型 →
null(包括String、List、自定义对象等) - 不调用构造函数重置,也不执行字段初始化表达式(如
private List<string> cache = new ArrayList();</string>中的右侧初始化会被忽略)
- 基本类型 →
-
类型无关性
transient的作用只取决于“是否被修饰”,与字段声明类型是否可序列化无关:- 即使是
transient File file;(File可序列化),它也不会被保存 - 即使是
transient Socket socket;(Socket不可序列化),也不会因类型问题报错——因为它根本不会被尝试序列化
- 即使是
-
不改变字段本身的语义或生命周期
transient仅影响序列化行为,不影响:- 该字段在内存中的读写、赋值、使用
- 是否能被反射访问(
getDeclaredField(...).get(obj)仍可获取当前值) - 是否参与
equals/hashCode/toString(除非你手动排除)
与
static的区别需注意static字段天然不参与序列化(属于类,不属于对象),加不加transient都一样被跳过;而transient专用于实例字段,强调“这是对象的一部分,但这次不想存”。
如果需要更精细控制(比如想临时加密保存 transient 字段),可通过自定义 private void writeObject(ObjectOutputStream s) 和 private void readObject(ObjectInputStream s) 方法,在其中手动 s.defaultWriteObject() 后再写入/读取特定 transient 字段。但这属于主动干预,默认机制就是跳过+设默认值。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











