7

假设我有一个类的版本,MyClass 其中我有两个字段int countString name. 我已经将字节流保存到文件中。在我从类中删除属性name之后,持久化的字节流也将毫无问题地转换为对象。

但根据 Serializable文档adding new attribute is compatible change but deleting attribute is incompatible change w.r.t. Serilaization。我很困惑有人可以帮助我理解这一点。谢谢!!!!

4

2 回答 2

12

几点:

反序列化对象时,字节流中未找到的任何字段都将初始化为null. 因此,当您添加新字段时,当从旧版本字节流反序列化新版本对象时,新字段将被初始化为null. 如果null被认为是无效值,您可以提供一种readObject方法来处理转换。旧版本仍然可以从新的字节流中反序列化——新字段被忽略。

如果一个字段被删除,情况正好相反:旧版本的类现在将缺少一个字段。缺少的字段将设置为null。但是,与前一种情况不同的是,旧版本不能添加readObject方法(如果您可以添加该方法,那么它将成为最新的新版本)。因此,删除一个字段被认为是不兼容的。

总之,readObject在新版本类中创建方法的能力允许它在添加新字段时处理旧版本字节流。不幸的是,反过来是不可能的。

重要的是要注意,除非特别定义,否则该serialVersionUID字段将自动生成,并且很可能会随着类的几乎所有显着更改而更改。如果两个类版本不同serialVersionUID,则在尝试对旧版本或新版本字节流执行序列化/反序列化时将引发异常。如果您不手动设置serialVersionUID,那么您的类的任何版本都不会在序列化方面兼容。

PS如果null恰好是已删除字段的有效状态(在旧版本中),那么我想您可以删除字段。但是,这可能是一个极端情况。

于 2013-04-28T09:39:51.447 回答
3

如果 serialVersionUID 保持不变,字段的添加和删除在对象序列化规范的对象版本控制章节中定义的规则下都是兼容的,您当然应该阅读。

于 2013-04-28T22:15:07.300 回答