【问题标题】:Serialization version uid in JavaJava中的序列化版本uid
【发布时间】:2012-04-20 06:49:32
【问题描述】:

Serialization id 是如何存储在对象的实例中的?

我们在Java中声明的Serialization id是静态字段;而静态字段是不被序列化的。

那么应该有一些方法来存储静态最终字段。 java是怎么做到的?

【问题讨论】:

    标签: java serialization


    【解决方案1】:

    serialVersionUID 不存储在“序列化”对象的实例中,因为它是一个静态字段(它是类的一部分,而不是对象的一部分)。

    因此,编译后的字节码中如果实际定义为stored,否则计算。用java specification的话来说:

    如果类已定义 serialVersionUID,则从类中检索它。如果 serialVersionUID > 未由类定义,则根据虚拟机中的类定义计算。如果>指定的类不可序列化或可外部化,则返回null。

    Stream Unique Identifiers section 中解释了这种计算的算法。

    这一段值得注意(这就是为什么 IDE 通常在实现 Serializable 的类没有明确定义 serialVersionUID 时显示警告的原因)。

    注意:强烈建议所有可序列化的类都显式声明 serialVersionUID 值,因为默认的 serialVersionUID 计算对类细节高度敏感可能因编译器实现而异,因此可能会在反序列化过程中导致意外的 serialVersionUID 冲突,从而导致反序列化失败。

    【讨论】:

    • 一个“相对”的反对票。必须确保 Jiri 的更好答案排在首位(否则不会被否决)。您完全忽略了问题的核心,即JVM如何知道序列化数据的版本(如果它的UID没有写入流,当然是,即使它是静态字段)。
    【解决方案2】:

    如果您查看java.io.ObjectStreamClass,您可以看到它实际上正在被序列化。以下方法:

    java.io.ObjectOutputStream.writeClassDescriptor(ObjectStreamClass)

    调用一个调用以下方法的方法:

    java.io.ObjectStreamClass.getSerialVersionUID()

    要么计算serialVersionUID,要么使用在类中声明并在调用以下方法之前找到的那个:

    java.io.ObjectStreamClass.getDeclaredSUID(Class)

    所以这个静态字段似乎是静态字段不被序列化规则的一个例外。

    如何阅读它被描述here

    【讨论】:

      【解决方案3】:

      序列版 UID 不存储在对象中;它是一个静态字段,因此它存储在类定义中。发生的情况是,当您序列化一个对象时,也必须存储有关其类的信息;否则将无法取消序列化对象。存储的有关该类的信息包括其名称及其序列版本 UID。

      您可以在此处阅读整个协议:http://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html

      总之,一个新对象的入口就是:

      newObject:
        TC_OBJECT classDesc newHandle classdata[]
      

      这里classDesc 是类的描述符,可以是新类的声明、空引用或对先前声明的类的引用:

      classDesc:
        newClassDesc
        nullReference
        (ClassDesc)prevObject
      

      新类的声明建立了类的名称和序列版本 UID、可用于稍后引用它的句柄,以及编码为 classDescInfo 的类的附加信息:

      newClassDesc:
        TC_CLASSDESC className serialVersionUID newHandle classDescInfo
      

      【讨论】:

        【解决方案4】:

        serialVersionUID 是序列化运行时使用的特殊字段。这一切都在java.lang.Serializable的Java Doc中进行了描述

        【讨论】:

          猜你喜欢
          • 2011-07-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-10
          • 2013-08-16
          • 2014-03-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多