假设我有类MyClass
的版本,其中我有两个字段int count
和String name
。我已经将字节流保存到文件中。从类中删除属性name
后,持久化的字节流也会转换为对象而没有问题。
但根据Serializable
文档adding new attribute is compatible change but deleting attribute is incompatible change w.r.t. Serilaization
。我很困惑,有人可以帮我理解这一点。感谢!!!!
答案 0 :(得分:11)
几点:
反序列化对象时,字节流中找到的任何 字段都将初始化为null
。因此,当您添加新字段时,当从旧版本字节流反序列化新版本对象时,新字段将初始化为null
。如果null
被视为无效值,您可以提供readObject
方法来处理转化。旧版本仍然可以从新的字节流中反序列化 - 新字段只是被忽略。
如果字段已删除,则情况相反:旧版本类现在将缺少字段。缺失的字段将设置为null
。但是,与前一种情况不同,旧版本无法添加readObject
方法(如果您可以添加该方法,那么它将成为最新的新版本)。因此,删除字段被视为不兼容。
总之,在新版本类中创建readObject
方法的能力允许它在添加新字段时处理旧版本的字节流。不幸的是,反过来是不可能的。
重要的是要注意,除非特别定义,否则serialVersionUID
字段将自动生成,并且很可能随着对类的所有显着更改而改变。如果两个类版本具有不同的serialVersionUID
,则在尝试对较旧或较新版本的字节流执行序列化/反序列化时将抛出异常。如果您未手动设置serialVersionUID
,那么您的类的任何版本都不会兼容序列化。
P.S。如果null
恰好是已删除字段的有效状态(在旧版本中),那么我猜您可以删除字段。然而,这可能是一个边缘情况。
答案 1 :(得分:2)
如果serialVersionUID保持不变,字段的添加和删除都是在对象序列化规范的对象版本控制章节中定义的规则下兼容的,您当然应该阅读这些规则。