5

我有以下类签名和ClientEventSourc实现Serializable

public class Grid extends ClientEventSource implements Focusable, FramingBlockWrapper,LIMSEditableField

现在FindBugs将其列为狡猾:

类是可序列化的,但没有定义 serialVersionUID

此类实现 Serializable 接口,但未定义 serialVersionUID 字段。像添加对 .class 对象的引用这样简单的更改将为类添加合成字段,这将不幸地更改隐式 serialVersionUID(例如,添加对 String.class 的引用将生成静态字段 class$java$lang$String )。此外,字节码编译器的不同源代码可能对为引用类对象或内部类而生成的合成变量使用不同的命名约定。要确保 Serializable 跨版本的互操作性,请考虑添加显式 serialVersionUID。

有人可以解释它的含义以及解决此问题的最佳方法是什么?

4

3 回答 3

8

serialVersionUID 用于反序列化您的类。它是默认自动生成的。
但是更改类中的任何内容都会生成不同的serialVersionUID,并且您无法反序列化“旧”对象。
所以你定义你自己的 serialVersionUID 来帮助反序列化找到正确的类。

将这样的变量添加到您的代码中:

private static final long serialVersionUID = 6106269076155338045L;

有关生成 UID 的参考:

在 Java 中扩展 Serializable 类时,我为 serialVersionUID 选择什么重要吗?

于 2012-08-09T10:46:26.477 回答
3

有人能解释一下这是什么意思吗

对类的微小更改会更改serialVersionUID您不想要的内容,因为这可能会无缘无故地阻止反序列化。

解决此问题的最佳方法是什么?

按照它的建议设置它。

private static final long serialVersionUID = 1;

有没有生成这个数字的算法/程序

是的。这是您试图绕过而不是重新创建的算法。刚开始1

我的意思是它可以是任何东西,或者它需要遵循某些最佳实践

我建议使用1是最佳实践,因为它清楚地表明这是任意选择的覆盖值。使用较大的值 like6106269076155338045L可能看起来像一个生成的数字或选择这个数字的原因。

于 2012-08-09T10:47:12.987 回答
1

该值用于反序列化。其目的是维护类与其对应的序列化对象之间的兼容性。如果你序列化一个类型的对象A然后A以某种方式改变,那么这个机制会阻止你反序列化对象;对象和它的类不匹配,你会得到运行时错误。

JDK中有一个serialver.exe。如果你给它一个.class文件作为参数,它会吐出一个serialVersionUID. 大多数 IDE 都内置了此功能。

输入示例:

> serialver MyClass

(已经存在一个文件MyClass.classMyClass必须实现Serializable

输出示例:

> MyClass: static final long serialVersionUID = -8174364448753809256L;

如果你讨厌在命令行中做事,那么像这样执行程序:

> serialver -show

将显示此 GUI:

串行器截图

然后,您可以输入班级名称并单击“显示”。

如果您感兴趣,我建议您阅读有关序列化过程的信息。您将确切了解为什么需要此版本 ID,生成它时考虑了哪些字段/方法等等。

于 2012-08-09T11:13:47.560 回答