静态变量反序列化后显示当前JVM中类的最新值,因其未被序列化而直接沿用类加载时的值;Java序列化仅保存实例字段,static字段存于方法区,ObjectOutputStream自动跳过;反序列化时不读取字节流中的static值,而是使用当前JVM中已有的静态变量值。

静态变量在反序列化后显示的是当前 JVM 中类的最新值,不是因为它被“恢复”了,而是因为它根本没被序列化过——它压根就没进字节流。
静态变量不属于对象实例状态
Java 序列化只保存对象的实例字段(即每个对象独有的数据),而静态变量属于类本身,存放在方法区(或元空间),生命周期与类绑定,和具体对象无关。ObjectOutputStream 在写入对象时会自动跳过所有 static 修饰的字段,不写入任何字节。
反序列化时静态值来自当前类加载状态
反序列化过程重建对象时,JVM 不会从字节流里读取静态字段,而是直接使用该类在当前 JVM 中已有的静态变量值。这个值可能已被其他代码修改过,比如:
- 序列化前 staticValue = 200
- 中间某处执行了 MyClass.staticValue = 300
- 反序列化后新对象看到的 staticValue 就是 300,和序列化动作完全无关
验证方式很简单
你可以做个小实验:序列化一个对象后,修改类的静态变量,再反序列化——结果一定反映修改后的值;或者把序列化后的文件拿到另一个刚启动、还没动过静态变量的 JVM 里反序列化,此时看到的就是类初始定义的值(比如 public static int x = 10; 那就显示 10)。
立即学习“Java免费学习笔记(深入)”;
真要持久化静态数据得手动处理
如果业务上确实需要把某次的静态值一并保存,必须重写 writeObject 和 readObject 方法:
- 在 writeObject 中调用 defaultWriteObject() 后,再用 out.writeInt(MyClass.staticVar) 显式写出
- 在 readObject 中调用 defaultReadObject() 后,再用 in.readInt() 读出并赋给 MyClass.staticVar
- 注意静态字段需是 public,或提供可访问的 static setter,否则无法安全赋值


















