【发布时间】:2011-09-07 05:59:02
【问题描述】:
当我使用 ObjectInputStream 读取与程序中当前定义的对象不兼容的序列化对象时会发生什么? 我会得到异常还是完全损坏的数据?
如果我在编译较新版本时更新了 serialVersionUID(根据需要),会有什么不同吗?
我环顾四周,似乎找不到发生了什么 - 只是您必须更新 serialVersionUID。
【问题讨论】:
标签: android serialization deserialization
当我使用 ObjectInputStream 读取与程序中当前定义的对象不兼容的序列化对象时会发生什么? 我会得到异常还是完全损坏的数据?
如果我在编译较新版本时更新了 serialVersionUID(根据需要),会有什么不同吗?
我环顾四周,似乎找不到发生了什么 - 只是您必须更新 serialVersionUID。
【问题讨论】:
标签: android serialization deserialization
如果隐式或显式 serialVersionUID 不匹配,则会出现如下异常:
java.io.InvalidClassException: SerialVersionUID; local class incompatible: stream classdesc serialVersionUID = 2, local class serialVersionUID = 3
【讨论】:
This answer 总结:
假设您有一个名为 Foo 的类,它没有 serialversionuid(默认值),并且您将 Foo 的一个实例序列化到一个文件中。稍后,您将一些新成员添加到 Foo 类。如果您尝试从文件中反序列化 Foo 对象,您将收到序列化失败,说明对象不兼容。它们是不兼容的,这是您想要的并且是默认设置。它们是不兼容的,因为 Foo 类中的新成员无法从 Foo 的旧序列化实例初始化。
现在,您可能会说,“我不在乎,在我的应用程序中,这些字段未初始化是可以接受的”。如果确实如此,您可以将 NEW Foo 类的 serialversionuid 设置为与 OLD Foo 类相同。这将告诉 Java 对象在可序列化方面是兼容的,并且当您将旧的 Foo 实例反序列化为新的 Foo 类时,Java 不会抱怨(但新字段仍将未初始化)。
如果您是第一次创建新类,并且设置了 serialversionuid,则您正在签订合同。您是说,“对于具有相同 serialversionuid 的此类的所有未来版本,我将保证它们在状态和序列化方面兼容”。
如果您更改了一个类,并且您明确希望禁止对旧版本进行反序列化,则可以将 serialversionuid 更改为新值。如果尝试将旧对象反序列化为新的类实例,这将导致抛出异常。
【讨论】: