当类在Eclipse中实现Serializable时,我有两个选项:添加默认的serialVersionUID(1L)或生成的serialVersionUID(3567653491060394677L)。我认为第一个选项更酷,但很多次我看到人们使用第二个选项。是否有理由生成较长的serialVersionUID?


当前回答

据我所知,这只是为了与以前的版本兼容。只有当您之前忽略了使用serialVersionUID,然后进行了您知道应该是兼容的但导致序列化中断的更改时,这才有用。

有关更多细节,请参阅Java Serialization Spec。

其他回答

生成一个类的主要原因是使它与已经有持久化副本的类的现有版本兼容。

因为在许多情况下,默认id不是唯一的。所以我们创建id是为了创造独特的概念。

序列化版本UID的目的是跟踪类的不同版本,以便执行有效的对象序列化。

其思想是生成一个对类的特定版本唯一的ID,然后在向类添加新细节(例如新字段)时更改该ID,这将影响序列化对象的结构。

总是使用相同的ID(例如1L)意味着在将来,如果类定义发生更改,导致序列化对象的结构发生更改,那么在尝试反序列化对象时很可能会出现问题。

如果省略了ID, Java将根据对象的字段实际为您计算ID,但我认为这是一个开销很大的过程,因此手动提供一个将提高性能。

下面是一些讨论类的序列化和版本控制的文章的链接:

JDC技术提示:2000年2月29日(链接在2013年2月中断) 了解Java Serialization API的秘密

当您使用serialVersionUID(1L)而不是生成serialVersionUID(3567653491060394677L)时,您是在说一些事情。

您是在说,您100%确信没有系统会接触到这个类,而这个类的版本号为1的序列化版本是不兼容的。

如果您能想出任何理由来说明它的序列化版本历史是未知的,那可能很难有信心地说出来。在它的生命周期中,一个成功的类将由许多人维护,存在于许多项目中,并驻留在许多系统中。

你可以为此苦恼。或者你可以买彩票,希望输。如果您生成了这个版本,那么就有很小的出错几率。如果你假设“嘿,我敢打赌还没有人使用1”,那么你的几率就很大。正是因为我们都认为0和1很酷,所以你击中它们的几率更高。

-

当您生成serialVersionUID(3567653491060394677L)而不是使用serialVersionUID(1L)时,您是在说一些事情。

你是说人们可能在这个类的历史上手动创建或生成了其他版本号,你不在乎,因为long是非常大的数字。

无论哪种方式,除非您完全了解在序列化该类时所使用的版本号的历史,以及该类已经存在或将存在的整个宇宙,否则您都是在冒险。如果你有时间100%确定1是ok的,那就试试吧。如果工作量太大,那就盲目地生成数字。你中彩票的可能性比出错的可能性更大。如果有,告诉我,我请你喝杯啤酒。

说了这么多玩彩票的内容,我可能给您的印象是serialVersionUID是随机生成的。事实上,只要数字的范围均匀分布在long的每个可能值上,就可以了。然而,它实际上是这样做的:

http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100

唯一的区别是你不需要随机来源。您正在使用类本身的更改来更改结果。但根据鸽子洞原理,它仍然有可能出错并发生碰撞。这简直太不可能了。祝你能从我嘴里套出啤酒来。

然而,即使类永远只存在于一个系统和一个代码库中,认为手动增加数量会导致零碰撞的可能性只意味着您不了解人类。:)

如果您没有指定serialVersionUID,那么Java会动态生成一个。生成的serialVersionUID就是这个数字。如果您更改了类中的某些内容,而这些内容并没有真正使您的类与以前的序列化版本不兼容,而是更改了散列,那么您需要使用生成的非常大的数字serialVersionUID(或错误消息中的“预期”数字)。否则,如果你自己记录所有东西,0,1,2…是更好的。