【问题标题】:Understanding of FindBugs warning about serialVersionUID field对serialVersionUID字段的FindBugs警告的理解
【发布时间】:2012-08-09 10:43:06
【问题描述】:

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

public class Grid extends ClientEventSource implements Focusable, FramingBlockWrapper,LIMSEditableField

现在FindBugs 将其列为狡猾:

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

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

能否解释一下它的含义以及解决此问题的最佳方法是什么?

【问题讨论】:

    标签: java serialization


    【解决方案1】:

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

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

    private static final long serialVersionUID = 6106269076155338045L;
    

    关于生成 UID 的参考:

    Does it matter what I choose for serialVersionUID when extending Serializable classes in Java?

    【讨论】:

    • 是否有任何算法/程序可以生成这个数字?我的意思是它可以是任何东西,或者它需要遵循某些最佳实践,就像 hashcode() 在 Effective java book 中描述的那样,并在 apache commons 的 EqualsBuilder 和 HashCodeBuilder 中实现。
    • 这个数字可以是任何东西,只要它在你的序列化类中是唯一的。日食有自己的生成器,但你可以使用任何数字。
    【解决方案2】:

    能解释一下是什么意思吗

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

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

    按照建议设置。

    private static final long serialVersionUID = 1;
    

    是否有任何算法/程序可以生成这个数字

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

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

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

    【讨论】:

    • 这是一个不错的选择吗?你能回答我对 Kostronor 的回答的评论吗?
    • 值的选择无关紧要。每当您进行重大更改时,您都应该更改它。即,每当您进行更改时,您不希望其他版本反序列化为此版本。以我的经验,这几乎从来没有。 ;)
    【解决方案3】:

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

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

    输入示例:

    > serialver MyClass
    

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

    输出示例:

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

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

    > serialver -show
    

    将显示此 GUI:

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

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

    【讨论】:

    • 你知道如何在 Intellij Idea 中做到这一点吗?
    • @Geek 不,抱歉。我只使用那个 IDE 几个小时......我知道如何在 Eclipse 和 Netbeans 中做到这一点。
    猜你喜欢
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2018-09-15
    相关资源
    最近更新 更多