【问题标题】:Java serialization, UID not changed. Can I add new variables and method to the class?Java 序列化,UID 没有改变。我可以在类中添加新的变量和方法吗?
【发布时间】:2010-11-08 14:18:28
【问题描述】:

我有一个序列化的类。现在我需要使用 setter 和 getter 方法在类中添加一个新变量。此类在 RMI 中通过线路发送。

在不更改 UID 的情况下,我可以为其添加新参数以及 getter 和 setter 方法吗?我尝试编写一个通过线路发送的示例类,并且没有更改 UID,并为其添加了新参数以及 getter 和 setter 方法。另一方面,我测试了它,我仍然正确地得到了值。我曾假设,如果我添加新参数、getter 和 setter 方法,我需要更改 UID。我错了吗?

【问题讨论】:

    标签: java serialization


    【解决方案1】:

    如果您硬编码一个类的 SerialVersionUID(通常为 1L),存储一些实例,然后重新定义该类,您基本上会得到这种行为(这或多或少是常识):

    1. 新字段(存在于类定义中,不存在于序列化实例中)被分配了一个默认值,对于对象为 null,或者对于原语,该值与未初始化的字段相同。
    2. 删除的字段(类定义中不存在,但序列化实例中存在)将被忽略。

    因此,一般的经验法则是,如果您只是添加字段和方法,并且不更改任何现有内容,并且如果您对这些新字段的默认值没问题,那么您通常没问题。

    【讨论】:

    【解决方案2】:

    哇,很多不好的信息。

    Java 序列化 + 非常 + 健壮。有一组非常明确的规则来管理具有相同 uid 和不同数据的对象的向后兼容性。基本思想是,只要不改变现有成员的类型,就可以保持相同的 uid 而不会出现数据问题。

    也就是说,您的代码仍然需要聪明地处理可能丢失数据的类。该对象可能会正确反序列化,但某些字段中可能没有数据(例如,如果您向类添加了一个字段并且正在反序列化该类的旧版本)。如果您的代码可以处理这个问题,那么您可能可以保留当前的 ​​uid。如果没有,那么你应该改变它。

    除了预定义的规则之外,还有一些高级使用场景,您甚至可以更改现有字段的类型并仍然设法反序列化数据,但这通常仅在极端情况下才需要。

    java 序列化在网上有很好的记录,您应该可以在相关的 sun/oracle 教程/文档中找到所有这些信息。

    【讨论】:

    • 一个链接将不胜感激。
    【解决方案3】:

    想要定义几个点来突出影响序列化的变化。 您将在下面找到指向 Oracle Java 文档的链接以了解更多详细信息。

    不兼容的更改

    对类的不兼容更改是那些无法保证互操作性的更改。进化类时可能发生的不兼容变化是:

    1. 删除字段
    2. 在层次结构中向上或向下移动类
    3. 将非静态字段更改为静态或将非瞬态字段更改为瞬态
    4. 更改原始字段的声明类型
    5. 更改 writeObject 或 readObject 方法,使其不再写入或读取默认字段数据,或更改它以尝试写入或读取,而之前的版本没有。
    6. 将类从 Serializable 更改为 Externalizable,反之亦然。
    7. 将类从非枚举类型更改为枚举类型,反之亦然。
    8. 删除 Serializable 或 Externalizable。
    9. 向类添加 writeReplace 或 readResolve 方法,前提是该行为会生成与任何旧版本类不兼容的对象。

    获取上述信息的链接 http://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html#6678

    【讨论】:

    • 非常好的剪切和粘贴,但实际上并没有回答具体问题。
    【解决方案4】:

    这仅在您让 Java 为您的类生成默认 UID 时才重要。它使用类的实际成员和方法来生成它,因此一旦您更改类结构,它就会失效。如果您为您的类提供 UID,那么这仅在您需要从文件等反序列化旧版本的类时才重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-09
      • 2020-10-18
      • 1970-01-01
      • 2010-09-10
      • 2015-11-19
      • 1970-01-01
      • 2019-08-02
      • 2010-09-15
      相关资源
      最近更新 更多