我正在浏览 Effective Java,第75项:
如果所有实例字段都是瞬态的,则在技术上允许 不需要调用defaultWriteObject和defaultReadObject,但是 不推荐。即使所有实例字段都是瞬态的, 调用defaultWriteObject会影响序列化表单,从而导致 大大增强了灵活性生成的序列化表单使其成为现实 可以在以后的版本中添加非瞬态实例字段 保持向后和向前兼容性。如果是一个实例 在更高版本中序列化并在早期版本中反序列化, 添加的字段将被忽略。有早期版本的readObject 方法无法调用defaultReadObject,反序列化会 使用StreamCorruptedException失败
问题是为什么需要调用defaultReadObject / defaultWriteObject来保持向后和向前兼容性?
你能用一个例子解释一下吗?
为什么添加的字段会被忽略?
为什么会抛出StreamCorruptedException?
答案 0 :(得分:0)
因为那是默认情况。如果你添加这些方法,你必须至少做一些如果它们不存在会发生的事情。否则,您将无法以兼容的方式读取/写入流。你不能完全取代原本写的内容而不会有兼容性。
除非你可以同时神奇地改变两端和,否则任何地方都没有永久序列化的流,例如在文件或数据库中。
答案 1 :(得分:0)
你的问题的答案实际上在你刚才提供的摘录中(虽然它有点模糊,我承认)。关键部分是:
如果某个实例在更高版本中序列化并在其中反序列化 在早期版本中,添加的字段将被忽略。 早些时候 version的readObject方法无法调用defaultReadObject ,即 反序列化将失败[...]
想象一下以下示例:
你有一个只有瞬态字段的对象。您决定跳过defaultWriteObject/defaultReadObject
次来电,因为您认为您不需要。
然后向程序添加新功能,并为此对象添加一些非瞬态字段。这次你可以正确地调用defaultWriteObject
,并且你希望旧版本的应用程序仍然可以运行(当然忽略新字段)。但它没有赢。您没有忽略刚添加的新字段,因为它在那里发现了意外数据。