java中的序列化

java中的序列化,java,serialization,Java,Serialization,我们的代码中有一个java类实现了Serializable。它已经在类中定义了SerialVersionUID。除此之外,我们还有一个 静态最终字符串sVersion,是一个整数。此类实现readObject和writeObject api。在readObject API中,它使用InputStream填充所有成员变量,在writeObject API中,它获取OutputStream并调用writeObject方法 现在我需要为这个类添加一个布尔数组作为属性。我应该更改SerialVersio

我们的代码中有一个java类实现了Serializable。它已经在类中定义了SerialVersionUID。除此之外,我们还有一个

静态最终字符串sVersion,是一个整数。此类实现readObject和writeObject api。在readObject API中,它使用InputStream填充所有成员变量,在writeObject API中,它获取OutputStream并调用writeObject方法

现在我需要为这个类添加一个布尔数组作为属性。我应该更改SerialVersionUID吗?如果我更改/不更改版本id,会产生什么影响? 最佳实践是什么?我试图学习joshua bloch的高效java,但需要一个简单易懂的答案


谢谢

如果您可能最终尝试反序列化该类的不兼容实例,那么是的,您肯定应该更新serialVersionUID。另一方面,如果您的程序总是序列化和反序列化数据,而不将其保存到持久性存储,或者仍然可以保证类与其调用方之间的约定,那么您不需要更改serialVersionUID

有关更多信息,请参阅和

此类实现readObject和writeObject api。在readObject API中,它使用InputStream填充所有成员变量,在writeObject API中,它获取OutputStream并调用writeObject方法

为什么??如果您根本不提供这些方法,那么这就是默认操作。[虽然我不知道您所说的“获取输出流”的确切含义,除非您指的是作为参数提供的输出流。]

然而,现在您已经到了这里,在
readObject()
中所要做的就是尝试读取新字段,并捕获在它们不存在时抛出的异常(
OptionalDataException
?),然后在
writeObject()
中写出额外的字段

不要更改
serialVersionUID
相反,您应该探索序列化的广泛对象版本控制支持,(a)确保类现在确实是序列化不兼容的,这在规范中是很难实现的;(b) 尝试自定义读/写对象()方法、readResolve/writeReplace()方法、serializableFields声明等方案,以确保流保持兼容。改变实际的serialVersionUID是最后的手段,是绝望的忠告


在进行任何进一步的操作之前,您需要真正仔细地看一下。序列化对类演化的支持要比大多数人所知道的多得多,包括对这个问题和他们所链接的问题的其他回答者。

好吧,我希望我的类也能与旧版本兼容。因此,在阅读了您发送给我的链接后,我认为不应该更改versionId。但是,当read对象方法尝试读取新的布尔数组时,我得到一个OptionalDataException,当我查看OptionalDataException时,我理解是试图读取超过类定义的readObject或readExternal方法所消耗的数据的末尾。在这种情况下,OptionalDataException的eof字段设置为true,长度字段设置为0。“如果您可能最终尝试反序列化该类的不兼容实例,那么是的,您肯定应该更新serialVersionUID”。这是一个循环论证。只有更改
serialVersionUID
才能使实例不兼容。仅仅添加一个字段并不能做到这一点。@EJP您在回答中共享的链接讨论了“不兼容的更改”,这些更改会影响类与其调用方之间的约定,从而无法保持互操作性。这就是我所说的“不兼容”。其目的是完全避免这些问题,而不是制定一个轻松递增
serialVersionUIDs
的策略。它们是非常剧烈的:字段类型更改、继承层次结构更改、类/包名称更改,并且一旦您了解了约束,它们都是可以避免的。正如我在回答中所说,“更改实际的
serialVersionUID
是最后的手段,是绝望的忠告”。谢谢链接。还提到更改实际serialVersionUID是“最后的手段”: