当缺少serialVersionUID时,Eclipse会发出警告。
可序列化类Foo未声明静态finallong类型的serialVersionUID字段
什么是serialVersionUID,为什么它很重要?请显示缺少serialVersionUID将导致问题的示例。
当缺少serialVersionUID时,Eclipse会发出警告。
可序列化类Foo未声明静态finallong类型的serialVersionUID字段
什么是serialVersionUID,为什么它很重要?请显示缺少serialVersionUID将导致问题的示例。
当前回答
字段数据表示类中存储的一些信息。类实现Serializable接口,因此eclipse自动提供声明serialVersionUID字段。让我们从这里设置的值1开始。
如果您不希望出现警告,请使用以下选项:
@SuppressWarnings("serial")
其他回答
不用担心,默认计算非常好,可以满足999999%的情况。如果你遇到问题,你可以——正如已经说过的——在需要时引入UID(这是极不可能的)
什么是serialVersionUID,为什么要使用它?
SerialVersionUID是每个类的唯一标识符,JVM使用它来比较类的版本,以确保在序列化期间使用的相同类在反序列化期间加载。
指定一个可以提供更多控制,但如果不指定,JVM会生成一个。不同编译器生成的值可能不同。此外,有时您只是出于某种原因想要禁止旧序列化对象的反序列化[向后不兼容],在这种情况下,您只需更改serialVersionUID。
Serializable的javadocs表示:
默认的serialVersionUID计算对类高度敏感详细信息可能因编译器实现而异因此,在反序列化。
因此,您必须声明serialVersionUID,因为它给了我们更多的控制权。
这篇文章在这个话题上有一些好的观点。
字段数据表示类中存储的一些信息。类实现Serializable接口,因此eclipse自动提供声明serialVersionUID字段。让我们从这里设置的值1开始。
如果您不希望出现警告,请使用以下选项:
@SuppressWarnings("serial")
java.io.Serializable的文档可能与您将得到的解释一样好:
序列化运行时与每个可序列化类关联一个版本号,称为serialVersionUID,该版本号在反序列化期间用于验证序列化对象的发送方和接收方是否已为该对象加载了与序列化兼容的类。如果接收方为对象加载的类具有与对应发送方类不同的serialVersionUID,则反序列化将导致InvalidClassException。可序列化类可以通过声明一个名为serialVersionUID的字段来显式声明自己的serialVersionUID,该字段必须是静态的、final的和long类型:
ANY-ACCESS-MODIFIER静态最终长序列版本UID=42L;
如果可序列化类未显式声明serialVersionUID,则序列化运行时将根据该类的各个方面计算该类的默认serialVersionID值,如Java(TM)对象序列化规范中所述。但是,强烈建议所有可序列化类显式声明serialVersionUID值,因为默认的serialVersionUID计算对可能因编译器实现而异的类细节高度敏感,因此在反序列化期间可能会导致意外的InvalidClassExceptions。因此,为了保证不同java编译器实现之间的serialVersionUID值一致,可序列化类必须声明显式的serialVersion UID值。还强烈建议显式serialVersionUID声明在可能的情况下使用私有修饰符,因为此类声明仅适用于立即声明的类-serialVersionUID字段作为继承成员不有用。
要理解字段serialVersionUID的重要性,应该了解序列化/反序列化的工作原理。
当序列化一个Serializable类对象时,Java Runtime将一个序列版本号(称为serialVersionUID)与这个序列化对象相关联。在反序列化此序列化对象时,Java Runtime将序列化对象的serialVersionUID与类的serialVersion UID匹配。如果两者都相等,则只有它继续执行进一步的反序列化过程,否则抛出InvalidClassException。
因此,我们得出结论,要使序列化/反序列化过程成功,序列化对象的serialVersionUID必须与类的serialVersion UID等效。如果程序员在程序中显式指定serialVersionUID值,那么无论序列化和反序列化平台如何,相同的值都将与序列化对象和类相关联(例如,可以使用sun或MS JVM在类似windows的平台上进行序列化,而反序列化可以使用Zing JVM在不同的平台Linux上进行)。
但是,如果程序员未指定serialVersionUID,则在对任何对象进行Serialization\DeSerialization时,Java运行时会使用自己的算法来计算它。这种serialVersionUID计算算法因JRE而异。对象序列化的环境也可能使用一个JRE(例如:SUN JVM),而取消序列化的环境则使用LinuxJvm(zing)。在这种情况下,与序列化对象关联的serialVersionUID将不同于在取消序列化环境中计算的类的serialVersion UID。反过来,反序列化将不会成功。所以为了避免这种情况/问题,程序员必须始终指定Serializable类的serialVersionUID。