当缺少serialVersionUID时,Eclipse会发出警告。

可序列化类Foo未声明静态finallong类型的serialVersionUID字段

什么是serialVersionUID,为什么它很重要?请显示缺少serialVersionUID将导致问题的示例。


当前回答

我不能错过这个机会,插上乔什·布洛克(Josh Bloch)的书《有效的Java》(第二版)。第10章是关于Java序列化的不可或缺的资源。

根据Josh的说法,自动生成的UID是基于类名、实现的接口以及所有公共和受保护的成员生成的。以任何方式更改任何这些都将更改serialVersionUID。因此,只有当您确定不会有多个版本的类被串行化(跨进程或稍后从存储中检索)时,才不需要使用它们。

如果您现在忽略它们,然后发现需要以某种方式更改类,但保持与旧版本类的兼容性,则可以使用JDK工具serialver在旧类上生成serialVersionUID,并在新类上显式设置。(根据您的更改,您可能还需要通过添加writeObject和readObject方法来实现自定义序列化-请参阅Serializable javadoc或上述第10章。)

其他回答

“serialVersionUID”是一个64位数字,用于在反序列化过程中唯一标识类。序列化对象时,类的serialVersionUID也会写入文件。每当反序列化此对象时,java运行时都会从序列化数据中提取此serialVersionUID值,并比较与该类关联的相同值。如果两者不匹配,则将抛出“java.io.InvalidClassException”。

如果可序列化类未显式声明serialVersionUID,则序列化运行时将基于类的各个方面(如字段、方法等)计算该类的serialVersionID值。您可以参考此链接获取演示应用程序。

如果您永远不需要将对象序列化到字节数组并发送/存储它们,那么您就不必担心。如果需要,那么您必须考虑serialVersionUID,因为对象的反序列化程序会将其与其类加载器所具有的对象版本相匹配。在Java语言规范中了解更多有关它的信息。

简单解释:

您正在序列化数据吗?序列化基本上是将类数据写入文件/流等。反序列化是将数据读回类。你打算投入生产吗?如果您只是用不重要的/假的数据测试一些东西,那么不要担心它(除非您是直接测试序列化)。这是第一个版本吗?如果是,请将serialVersionUID设置为1L。这是第二、第三等prod版本吗?现在您需要担心serialVersionUID,并且应该深入研究它。

基本上,如果在更新需要写入/读取的类时没有正确更新版本,那么在尝试读取旧数据时会出现错误。

如果您序列化只是因为为了实现而必须序列化(例如,谁会关心您是否为HTTPSession序列化……如果它是否存储,您可能不关心对表单对象进行反序列化),那么您可以忽略这一点。

如果您实际使用的是序列化,那么只有计划直接使用序列化存储和检索对象时才重要。serialVersionUID表示类的版本,如果类的当前版本与其前一版本不向后兼容,则应递增该版本。

大多数时候,您可能不会直接使用序列化。如果是这种情况,请通过单击快速修复选项生成默认的SerialVersionUID,不用担心。

如果CheckStyle能够验证实现Serializable的类上的serialVersionUID是否具有良好的值,即它与串行版本id生成器将生成的值相匹配,这将是一件好事。例如,如果您有一个包含大量可序列化DTO的项目,那么记住删除现有的serialVersionUID并重新生成它是一件痛苦的事,而目前验证这一点的唯一方法(据我所知)是为每个类重新生成并与旧类进行比较。这是非常痛苦的。