【问题标题】:What happens when you deserialize an incompatible version反序列化不兼容的版本时会发生什么
【发布时间】:2011-09-07 05:59:02
【问题描述】:

当我使用 ObjectInputStream 读取与程序中当前定义的对象不兼容的序列化对象时会发生什么? 我会得到异常还是完全损坏的数据?

如果我在编译较新版本时更新了 serialVersionUID(根据需要),会有什么不同吗?

我环顾四周,似乎找不到发生了什么 - 只是您必须更新 serialVersionUID。

【问题讨论】:

    标签: android serialization deserialization


    【解决方案1】:

    如果隐式或显式 serialVersionUID 不匹配,则会出现如下异常:

    java.io.InvalidClassException: SerialVersionUID; local class incompatible: stream classdesc serialVersionUID = 2, local class serialVersionUID = 3
    

    【讨论】:

      【解决方案2】:

      This answer 总结:

      假设您有一个名为 Foo 的类,它没有 serialversionuid(默认值),并且您将 Foo 的一个实例序列化到一个文件中。稍后,您将一些新成员添加到 Foo 类。如果您尝试从文件中反序列化 Foo 对象,您将收到序列化失败,说明对象不兼容。它们是不兼容的,这是您想要的并且是默认设置。它们是不兼容的,因为 Foo 类中的新成员无法从 Foo 的旧序列化实例初始化。

      现在,您可能会说,“我不在乎,在我的应用程序中,这些字段未初始化是可以接受的”。如果确实如此,您可以将 NEW Foo 类的 serialversionuid 设置为与 OLD Foo 类相同。这将告诉 Java 对象在可序列化方面是兼容的,并且当您将旧的 Foo 实例反序列化为新的 Foo 类时,Java 不会抱怨(但新字段仍将未初始化)。

      如果您是第一次创建新类,并且设置了 serialversionuid,则您正在签订合同。您是说,“对于具有相同 serialversionuid 的此类的所有未来版本,我将保证它们在状态和序列化方面兼容”。

      如果您更改了一个类,并且您明确希望禁止对旧版本进行反序列化,则可以将 serialversionuid 更改为新值。如果尝试将旧对象反序列化为新的类实例,这将导致抛出异常。

      【讨论】:

      • 那里给出的使用自动定义值的想法怎么样?由于唯一一次可以改变的限制是在版本之间,我真的不介意我当时是否失去了当前状态。这只是一个纸牌游戏,所以如果你偶尔不能回到原来的位置,这并不是世界末日。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      相关资源
      最近更新 更多