Skip to content

serialVersionUID 不是被 static 变量修饰了吗?为什么还会被“序列化”?这个问题的回答是有问题的 #2174

Closed
@abekthink

Description

@abekthink

原文回答是:static 修饰的变量是静态变量,位于方法区,本身是不会被序列化的。 static 变量是属于类的而不是对象。你反序列之后,static 变量的值就像是默认赋予给了对象一样,看着就像是 static 变量被序列化,实际只是假象罢了。

这个回答本身是有问题的,如果是拿默认值序列化的话,那序列化的二进制字节流的serialVersionUID就应该是0,那对于接收方在反序列化的时候就无法再依据serialVersionUID是否一致来去判别了。
所以正确的答案是:static 修饰的变量是静态变量,位于方法区,本身是不会被序列化的。但是,serialVersionUID的序列化做了特殊处理,在序列化时,会将serialVersionUID序列化到二进制字节流中;在反序列化时,也会解析它并做一致性判断。

证明:拿ObjectOutputStream和ObjectInputStream的实现来看,在ObjectOutputStream.writeObject()时,底层调用了ObjectStreamClass.writeNonProxy()方法,其中包含了将serialVersionUID写入输出流;在ObjectInputStream.readObject()时,底层调用了ObjectStreamClass.readNonProxy()和ObjectStreamClass.initNonProxy()方法,前者用来从输入流里读取serialVersionUID,后者用来比对Class里的serialVersionUID和输入流里的serialVersionUID是否一致。

原文:https://github.com/Snailclimb/JavaGuide/blob/main/docs/java/basis/serialization.md#jdk-%E8%87%AA%E5%B8%A6%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96%E6%96%B9%E5%BC%8F

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugContent error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions