java 我什么时候必须更改 serialVersionUID?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3284979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 01:09:04  来源:igfitidea点击:

When do I have to change the serialVersionUID?

javaserialization

提问by Kyle

I know that I can use serialVersionUID to control the version of classes. And I read that I can then add or remove fields and the class will still be compatible, it will just use default values.

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

When mustI change the serialVersionUID?

我什么时候必须更改 serialVersionUID?

回答by Vineet Reynolds

The value of the serialVersionUID field is should ideally be changed when incompatible changes are made to the structure of the class. The complete list of incompatible changes is listed in the Java Object Serialization Specification.

当对类的结构进行不兼容的更改时,最好更改 serialVersionUID 字段的值。Java Object Serialization Specification 中列出了不兼容更改的完整列表。

To expand further, incompatible changes to a class will prevent the deserialization mechanism from creating an instance of the object, because there is information in the stream that does not map to the current class definition.

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

回答by user207421

The frequently-repeated mantra about changing the serialVersionUIDevery time you change the class is complete and utter nonsense. See this Sun articlewhich they republished on their site and which was migrated to the Oracle Technology Network after the acquisition.

serialVersionUID每次更改课程时经常重复的口头禅是完全无稽之谈。请参阅他们在其站点上重新发布并在收购后迁移到 Oracle 技术网的这篇 Sun 文章

You should change the serialVersionUIDonlywhen you deliberately want to break compatibility with all existing serializations, or when your changes to the class are so radical that you have no choice - in which case you should really think several times about what it is that you are actually doing.

serialVersionUID只有当您故意破坏与所有现有序列化的兼容性时,或者当您对类的更改如此激进以至于您别无选择时,应该更改 the - 在这种情况下,您应该真正考虑几次您实际上是什么正在做。

In all other cases you should bust your boiler trying to use custom readObject()/writeObject()and/or writeReplace()/readResolve()methods and/or serialFieldsannotations so that you can continue to read objects from those existing serializations. Once you break that you are in for a major headache, indeed nightmare.

在所有其他情况下,您应该阻止锅炉尝试使用自定义readObject()/writeObject()和/或writeReplace()/readResolve()方法和/或serialFields注释,以便您可以继续从那些现有的序列化中读取对象。一旦你打破它,你就会头痛,确实是噩梦。

回答by Tom G

If you don't specify a serialVersionUIDfield in your Serializableclasses, the Java compiler will specify one for you -- essentially it's a hash of the class name, interface names, methods, and fields of the class. Methods can be altered at any time, though, so if you need to change how a stored class is deserialized, you can override the readObject method. If you do specify the serialVersionUIDfield in your code, though, the compiler won't override that even if you do make incompatible changes, which can result in an exception at runtime -- your IDE or compiler won't give you a warning. (EDIT -- thanks EJP)IDEs such as Eclipse can insert the compiler's UID for you, if you want to easily check how the compiler views certain changes.

如果你没有serialVersionUID在你的Serializable类中指定一个字段,Java 编译器会为你指定一个——本质上它是类名、接口名、方法和类字段的散列。但是,方法可以随时更改,因此如果您需要更改存储类的反序列化方式,则可以覆盖 readObject 方法。但是,如果您确实serialVersionUID在代码中指定了该字段,即使您进行了不兼容的更改,编译器也不会覆盖它,这可能会导致运行时出现异常——您的 IDE 或编译器不会向您发出警告。(编辑 - 感谢 EJP)如果您想轻松检查编译器如何查看某些更改,Eclipse 等 IDE 可以为您插入编译器的 UID。

If you make changes often, keep an old version of the disk file around to test deserialization with. You can write unit tests to try and read in the old file, and see if it works or if it's totally incompatible.

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

One caveat, I've personally experienced the pain that is working with Serializableclasses originally intended for long-term storage that were improperly designed. For example, storing GUI elements on disk rather than creating them when needed. Ask yourself if Serializableis really the best way to save your data.

一个警告,我个人经历过使用Serializable最初用于长期存储但设计不当的类的痛苦。例如,将 GUI 元素存储在磁盘上而不是在需要时创建它们。问问自己这是否Serializable真的是保存数据的最佳方式。

回答by Malt

For the sake of completeness, here's a list of changes that break the compatibility of Java serialization according to the java 8 spec:

为了完整起见,这里列出了根据java 8 规范破坏 Java 序列化兼容性的更改列表:

  • Deleting fields
  • Moving classes up or down the hierarchy
  • Changing a nonstatic field to static or a nontransient field to transient
  • Changing the declared type of a primitive field
  • Changing the writeObject or readObject method so that it no longer writes or reads the default field data or changing it so that it attempts to write it or read it when the previous version did not.
  • Changing a class from Serializable to Externalizable or vice versa
  • Changing a class from a non-enum type to an enum type or vice versa
  • Removing either Serializable or Externalizable
  • Adding the writeReplace or readResolve method to a class
  • 删除字段
  • 在层次结构中向上或向下移动类
  • 将非静态字段更改为静态或将非瞬态字段更改为瞬态
  • 更改原始字段的声明类型
  • 更改 writeObject 或 readObject 方法,使其不再写入或读取默认字段数据,或更改它以尝试写入或读取它,而以前的版本没有。
  • 将类从 Serializable 更改为 Externalizable,反之亦然
  • 将类从非枚举类型更改为枚举类型,反之亦然
  • 删除 Serializable 或 Externalizable
  • 将 writeReplace 或 readResolve 方法添加到类

回答by Peter Lawrey

You can set serialiVersionUID to the same value for the life of the class. (Not always a good idea) Note: you can implement your own serialization version checking strategy with readObject/writeObject if you need this and leave the UID unchanged.

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

The only time you MUST change it is if you have already serialized some data to a file and you want to read it. If it has changed for any reason you MUST set the serialiVersionUID to the version in the file to have any hope of being able to read the data.

您必须更改它的唯一时间是如果您已经将一些数据序列化到一个文件并且您想要读取它。如果它因任何原因发生变化,您必须将 serialiVersionUID 设置为文件中的版本,以便能够读取数据。