Serialization - Manually defining a SerialVersionUID required?
我目前正试图证明移除findbugs/sonar中的规则是正当的,该规则分类使类可序列化,或者在大多数情况下,扩展我们的基类,使类可序列化而不需要开发人员实现,然后不定义serialversionID是一个严重错误!这当然会让我们的麻瓜管理(不是开发人员的读管理)恐慌,认为我们有必须修复的关键错误!
我的论点是,在Java的当前版本中,您不需要提供SerialValueUID,因为JVM会在您序列化类的情况下为您这样做,但是否有人指出了为什么在当今时代我们仍然应该提供UID而不是将其留给JVM的原因?从网络上看,我现在唯一能找到的提供uid的理由是不这样做是"糟糕的做法"。
有什么想法吗?
定义
现在讨论什么时候应该或不应该申报
如果您关心序列化兼容性,那么几乎应该总是声明一个
通过"关注序列化兼容性",假设您已经序列化了一个对象并将其存储在一个文件或数据库中。您希望系统的未来版本(具有类的进化版本)能够读取存储的序列化对象吗?或者,假设您序列化对象并通过网络将其发送给其他反序列化对象的应用程序。这在RMI中发生,或者如果您开发自己的网络协议来发送和接收序列化对象,就可能发生。如果是这样,那么在您的网络上,您的应用程序的不同版本是否可以在网络上的不同位置运行,并且您希望它们能够成功地相互通信?好的。
如果上述任何一个是正确的,那么您关心序列化兼容性,并且需要声明
有时,您可能关心序列化兼容性,但声明
有时您可能根本不关心不同类版本的序列化兼容性。好的。
一个例子是,如果您有一组紧密耦合的JVM,它们都共享来自同一类路径的类,并且它们正在交换序列化对象。因为它们使用的是相同的实际类,所以不能有任何不兼容。在这种情况下,为类声明一个
另一个原因是
还有一个例子是,您的产品需求(或其他)可能只是决定在某些情况下不关心序列化兼容性,或者根本不关心。您可能会认为这是"不受支持"的东西,JDK本身就采用了这种方法。通常,JDK中大多数公共的、可序列化的类都被约束为与前向和后向序列化兼容。因此,所有这些类都声明一个
归根结底,在继承
我想延伸我的方式,但要离开房间。
这些不是我的原始想法,而是约书亚·布洛赫的有效爪哇
理由1:串行对象可以持续
即使是小的,其他三维变化也会导致JVM生成不同的ID。所以当你尝试以一个老的,但其他相容的等级结构除去一个连续的对象时,结果是一个无效的等级结构。
改变一些无形的东西,如添加一个方便的存取到一个类别,会导致不同的被计算。同样,影响产生的UID的一个因素是私人成员。因此,你不仅限于改变公众对API的看法(这也许更为可取),而且还限于改变太大程度的私人执行细节,因为可能造成严重的不良后果。
另一种看待这一点的方法是手动定义UID,当你可以确保JVM试图以它的计数类来解答一个对象时,考虑到你的类中的变化,也可以防止JVM试图以它的计数类去解答一个对象(EG你的新类是不相容的)。是UID。
原因2:运行计算越来越普及
计算机设备在运行中被计算。手动描述这场比赛结束了这场比赛。
如果用于串行和D-Serializing的类别的版本与JVM S相同或不相符,则用串行路由产生的缺陷值对分类细节是敏感的。
查看Javadoc
The serialization runtime associates with each serializable class a version number,called a serialversionuid,which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classions for that object that are applicable with respect to serial如果接收者为具有不同序列的对象装载了一个等级,而不是相应的参与者的等级,那么将在一个致残的等级中解脱。a serializable class can declare its own serialversionuid explicitly by declaring a field named"serialversionuid"that must be static,final,and of type long:
*Any-access-change static final long serialversionuid=42l;
如果一个串行分类不明确声明一个串行分类,那么串行分类将计算一个串行值,该串行值基于分类的不同方面,如Java(TM)Object Serialization Specification。然而,它强烈建议,所有连续性类别解释性声明的序列价值,自从否定的序列式计算对分类细节有很大的敏感性,因为它可能对汇编执行情况产生很大的依赖性,并可在deserization过程中产生预期的致残性。因此,为了保证不同爪哇编译器实现的一致性,一个可串行编译器类别必须申报一个可串行编译的价值。它还强烈建议,解释性声明应连贯一致地使用私人修改,因为这种声明仅适用于立即宣布的类别——连贯一致的领域并不是作为原始成员使用的。Array classions cannot declare an explicit serialversionuid,so they always have the default computed value,but the requirement for matching serialversionuid values is waived for array classions.*