当类在Eclipse中实现Serializable时,我有两个选项:添加默认的serialVersionUID(1L)或生成的serialVersionUID(3567653491060394677L)。我认为第一个选项更酷,但很多次我看到人们使用第二个选项。是否有理由生成较长的serialVersionUID?
当前回答
当您使用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 Serialization Spec。
如果您没有指定serialVersionUID,那么Java会动态生成一个。生成的serialVersionUID就是这个数字。如果您更改了类中的某些内容,而这些内容并没有真正使您的类与以前的序列化版本不兼容,而是更改了散列,那么您需要使用生成的非常大的数字serialVersionUID(或错误消息中的“预期”数字)。否则,如果你自己记录所有东西,0,1,2…是更好的。
为了补充@David Schmitts的回答,作为经验法则,我总是使用默认的1L。我只需要返回并更改其中一些数几次,但当我进行更改并每次更新默认数时,我知道这一点。
在我目前的公司,他们要求自动生成的号码,所以我使用它作为约定,但我更喜欢默认的。我的观点是,如果这不是您工作的约定,请使用默认值,除非您认为由于某种原因将不断更改序列化类的结构。
serialVersionUID的“long”默认值是Java序列化规范定义的默认值,由默认序列化行为计算得出。
因此,如果您添加了默认版本号,只要在结构上没有任何变化,您的类就会(反)序列化得更快,但是您必须注意,如果您更改了类(添加/删除字段),那么您也会更新序列号。
如果你不需要兼容现有的比特流,你可以把1L放在那里,然后在有变化时根据需要增加版本。也就是说,当更改后的类的默认序列化版本与旧类的默认版本不同时。
推荐文章
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组
- Openssl不被视为内部或外部命令
- 如何添加自定义方法到Spring Data JPA
- 如何在Ubuntu中设置Java环境路径
- 无法执行dex:在Eclipse中超过GC开销限制
- 有人能解释一下JPA和Hibernate中的mappedBy吗?
- 是什么导致JNI调用变慢?
- Java中的&和&&有什么区别?
- 使用Java的Collections.singletonList()?
- Maven使用多个src目录编译
- 导入时无法解析符号