当类在Eclipse中实现Serializable时,我有两个选项:添加默认的serialVersionUID(1L)或生成的serialVersionUID(3567653491060394677L)。我认为第一个选项更酷,但很多次我看到人们使用第二个选项。是否有理由生成较长的serialVersionUID?
当前回答
序列化版本UID的目的是跟踪类的不同版本,以便执行有效的对象序列化。
其思想是生成一个对类的特定版本唯一的ID,然后在向类添加新细节(例如新字段)时更改该ID,这将影响序列化对象的结构。
总是使用相同的ID(例如1L)意味着在将来,如果类定义发生更改,导致序列化对象的结构发生更改,那么在尝试反序列化对象时很可能会出现问题。
如果省略了ID, Java将根据对象的字段实际为您计算ID,但我认为这是一个开销很大的过程,因此手动提供一个将提高性能。
下面是一些讨论类的序列化和版本控制的文章的链接:
JDC技术提示:2000年2月29日(链接在2013年2月中断) 了解Java Serialization API的秘密
其他回答
每次定义时,绝对应该创建一个serialVersionUID 实现java.io.Serializable的类。如果你不这样做,别人会的 自动为你创建,但这很糟糕。自动生成 serialVersionUID基于类的方法签名,因此 如果您在将来更改类以添加方法(例如), 反序列化类的“旧”版本将失败。这就是 可能发生:
创建类的第一个版本,而不定义 serialVersionUID。 将类的实例序列化到持久存储中;一个 serialVersionUID为您自动生成。 修改类以添加新方法,并重新部署应用程序。 尝试反序列化在第2步中序列化的实例,但现在它失败了(当它应该成功时),因为它有 不同的自动生成serialVersionUID。
为了补充@David Schmitts的回答,作为经验法则,我总是使用默认的1L。我只需要返回并更改其中一些数几次,但当我进行更改并每次更新默认数时,我知道这一点。
在我目前的公司,他们要求自动生成的号码,所以我使用它作为约定,但我更喜欢默认的。我的观点是,如果这不是您工作的约定,请使用默认值,除非您认为由于某种原因将不断更改序列化类的结构。
当您使用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…是更好的。
因为在许多情况下,默认id不是唯一的。所以我们创建id是为了创造独特的概念。
推荐文章
- IntelliJ IDEA with Junit 4.7”!!JUnit 3.8或更高版本:
- 既然JavaScript和Java没有任何关系,它为什么被称为JavaScript ?
- 番石榴vs Apache Commons
- Java是编译型编程语言还是解释型编程语言?
- 我如何通过Java应用程序使用GMail,雅虎或Hotmail发送电子邮件?
- 注释@GetMapping和@RequestMapping(method = RequestMethod.GET)之间的区别
- lambda表达式中使用的变量应该是final或有效final
- 如何创建数组列表的数组?
- noclassdeffounderror:无法初始化类XXX
- 如何创建今天午夜和明天午夜的Java日期对象?
- ByteBuffer在Java中的用途是什么?
- 使Hibernate忽略未映射的实例变量
- 映射enum在JPA与固定的值?
- 如何找到可用的端口?
- 假唤醒在Java中真的发生了吗?