Java的 – 我什么时候必须改变serialVersionUID?

我知道我可以使用serialVersionUID来控制类的版本。 而且我读过,然后我可以添加或删除字段,类将仍然兼容,它只会使用默认值。

何时必须更改serialVersionUID?

如果对类的结构进行不兼容的更改,则理想地应该更改serialVersionUID字段的值。 Java对象序列化规范中列出了不兼容的更改的完整列表。

若要进一步扩展,对类的不兼容更改将阻止反序列化机制创build对象的实例,因为stream中的信息不映射到当前类定义。

每当你改变类时,关于改变serialVersionUID的经常重复的咒语是完全的,完全是无稽之谈。 看到他们在其网站上重新发布的这篇Sun文章 ,并在收购之后将其迁移到了Oracle技术networking。

只有在故意要破坏与所有现有序列化的兼容性时,或者当您对类的更改过于激进以至于没有其他select时, 应该更改serialVersionUID ,在这种情况下,您应该多次思考自己是什么实际上在做。

在所有其他情况下,您应该尝试使用自定义的readObject()/writeObject()和/或writeReplace()/readResolve()方法和/或serialFields注释来serialFields您的serialFields以便您可以继续从这些现有的串行化中读取对象。 一旦你突破,你是在头痛,真是噩梦。

如果在Serializable类中没有指定serialVersionUID字段,那么Java编译器会为您指定一个字段 – 本质上它是类的名称,接口名称,方法和字段的散列。 但是,可以随时更改方法,所以如果需要更改存储类的反序列化方式,可以重写readObject方法。 但是,如果在代码中指定了serialVersionUID字段,那么即使您做出不兼容的更改(即在运行时会导致exception) ,编译器也不会覆盖该更改, 您的IDE或编译器不会给出警告。 (编辑 – 谢谢EJP)如果您想轻松地检查编译器如何查看某些更改,Eclipse等IDE可以为您插入编译器的UID。

如果您经常进行更改,请保留旧版本的磁盘文件以testing反序列化。 您可以编写unit testing来尝试读取旧文件,并查看它是否有效或者是否完全不兼容。

一个告诫,我亲身经历了与Serializable类一起工作的痛苦,原本是用于devise不当的长期存储。 例如,将GUI元素存储在磁盘上,而不是在需要时创build它们。 问问自己, Serializable是否真的是保存数据的最佳方式。

您可以将serialiVersionUID设置为类的生命期相同的值。 (并不总是一个好主意)注意:如果你需要这个,可以用readObject / writeObject实现你自己的序列化版本检查策略,并保持UID不变。

唯一一次你必须改变它是如果你已经序列化一些数据到一个文件,你想读它。 如果由于任何原因已经改变,你必须将serialiVersionUID设置为文件中的版本,以便能够读取数据。