我有以下类签名,ClientEventSourc
实现Serializable
:
public class Grid extends ClientEventSource implements Focusable, FramingBlockWrapper,LIMSEditableField
现在FindBugs将此列为狡猾:
Class是Serializable,但未定义serialVersionUID
此类实现Serializable接口,但未定义 serialVersionUID字段。更改就像添加引用一样简单 一个.class对象会将合成字段添加到类中 不幸的是,更改了隐含的serialVersionUID(例如,添加了一个 对String.class的引用将生成一个静态字段 类$ java的$ LANG $字符串)。此外,不同的源代码到字节码 编译器可以对合成变量使用不同的命名约定 生成用于引用类对象或内部类。确保 Serializable跨版本的互操作性,考虑添加一个 显式serialVersionUID。
有些人可以解释一下这意味着什么,以及解决这个问题的最佳方法是什么?
答案 0 :(得分:7)
serialVersionUID用于反序列化您的类。
它默认是自动生成的
但更改类中的任何内容都会生成不同的serialVersionUID,并且您无法反序列化“旧”对象。
所以你定义自己的serialVersionUID来帮助反序列化找到合适的类。
在您的代码中添加如下变量:
private static final long serialVersionUID = 6106269076155338045L;
有关生成UID的参考:
Does it matter what I choose for serialVersionUID when extending Serializable classes in Java?
答案 1 :(得分:2)
可以解释一下这意味着什么
对该类进行微小更改会更改您不想要的serialVersionUID
,因为这可以防止反序列化,没有充分的理由。
什么是解决此问题的最佳方法?
按照建议设置它。
private static final long serialVersionUID = 1;
是否有任何生成此号码的算法/程序
是。这是您试图绕过的算法,而不是重新创建的算法。从1
开始。
我的意思是它可以是任何东西,或者它需要遵循某些最佳实践
我建议使用1
是最佳做法,因为它清楚地表明这是一个任意选择的覆盖值。使用像6106269076155338045L
这样的大值可能看起来像生成的数字或选择了这个数字。
答案 2 :(得分:1)
此值用于反序列化。其目的是保持类及其相应的序列化对象之间的兼容性。如果序列化类型为A
的对象,然后以某种方式更改A
,则此机制会阻止您反序列化该对象;对象及其类不匹配,您将遇到运行时错误。
JDK中有serialver.exe
。如果你给它一个.class
文件作为参数,它会吐出serialVersionUID
。大多数IDE都内置了此功能。
输入示例:
> serialver MyClass
(已存在文件MyClass.class
且MyClass
必须实施Serializable
)
输出示例:
> MyClass: static final long serialVersionUID = -8174364448753809256L;
如果你讨厌在命令行做事,那么执行这样的程序:
> serialver -show
将显示此GUI:
然后您可以输入班级名称并单击“显示”。
如果您感兴趣,我建议您阅读序列化过程。您可以找到为什么需要此版本ID,生成它时考虑哪些字段/方法等等。