-
Notifications
You must be signed in to change notification settings - Fork 45.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
serialVersionUID 不是被 static 变量修饰了吗?为什么还会被“序列化”?这个问题的回答是有问题的 #2174
Labels
bug
Content error
Comments
静态变量在jdk 1.7开始,就移到了堆中,这里怎么又说是在方法区中呢 |
没注意到,JDK1.7 字符串常量池和静态变量从永久代移动了 Java 堆中。 |
已修改:
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
原文回答是: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
The text was updated successfully, but these errors were encountered: