当缺少serialVersionUID时,Eclipse会发出警告。
可序列化类Foo未声明静态finallong类型的serialVersionUID字段
什么是serialVersionUID,为什么它很重要?请显示缺少serialVersionUID将导致问题的示例。
当缺少serialVersionUID时,Eclipse会发出警告。
可序列化类Foo未声明静态finallong类型的serialVersionUID字段
什么是serialVersionUID,为什么它很重要?请显示缺少serialVersionUID将导致问题的示例。
当前回答
每次序列化对象时,对象都会标记对象类的版本ID号。此ID称为serialVersionUID,它是根据有关类结构的信息计算的。假设您创建了一个Employee类,它的版本id为#333(由JVM分配),现在当您将序列化该类的对象(假设Employees对象)时,JVM将为其分配UID为#333。
考虑一种情况——将来您需要编辑或更改类,在这种情况下,当您修改它时,JVM将为它分配一个新的UID(假设#444)。现在,当您尝试反序列化雇员对象时,JVM会将序列化对象(雇员对象)的版本ID(#333)与类的版本ID进行比较,即#444(自更改以来)。相比之下,JVM将发现两个版本UID不同,因此反序列化将失败。因此,如果每个类的serialVersionID由程序员自己定义。即使类在未来演变,它也将是相同的,因此JVM将始终发现类与序列化对象兼容,即使类已更改。有关更多信息,请参阅HEAD FIRST JAVA的第14章。
其他回答
您可以告诉Eclipse忽略这些serialVersionUID警告:
窗口>首选项>Java>编译器>错误/警告>潜在编程问题
如果您不知道,您可以在本节中启用许多其他警告(甚至将一些警告报告为错误),其中许多警告非常有用:
潜在的编程问题:可能的意外布尔赋值潜在编程问题:空指针访问不必要的代码:从不读取局部变量不必要的代码:冗余空检查不必要的代码:不必要的强制转换或“instanceof”
以及更多。
不用担心,默认计算非常好,可以满足999999%的情况。如果你遇到问题,你可以——正如已经说过的——在需要时引入UID(这是极不可能的)
SerialVersionUID用于对象的版本控制。也可以在类文件中指定serialVersionUID。不指定serialVersionUID的结果是,当您添加或修改类中的任何字段时,已经序列化的类将无法恢复,因为为新类和旧序列化对象生成的serialVersionID将不同。Java序列化过程依赖于正确的serialVersionUID来恢复序列化对象的状态,并在serialVersionID不匹配的情况下抛出Java.io.InvalidClassException
阅读更多信息:http://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html#ixzz3VQxnpOPZ
为什么在Java中的Serializable类中使用SerialVersionUID?
在序列化期间,Java运行时为类创建一个版本号,以便以后可以对其进行反序列化。此版本号在Java中称为SerialVersionUID。
SerialVersionUID用于序列化数据的版本。只有当类的SerialVersionUID与序列化实例匹配时,才能对其进行反序列化。当我们不在类中声明SerialVersionUID时,Java运行时会为我们生成它,但不建议这样做。建议将SerialVersionUID声明为私有静态最终长变量,以避免默认机制。
当您通过实现标记接口java.io.Serializable将类声明为Serializable时,如果您没有使用Externalizable接口自定义进程,java运行时将该类的实例通过默认Serialization机制持久化到磁盘中。
另请参阅为什么在Java中的Serializable类中使用SerialVersionUID
我不能错过这个机会,插上乔什·布洛克(Josh Bloch)的书《有效的Java》(第二版)。第10章是关于Java序列化的不可或缺的资源。
根据Josh的说法,自动生成的UID是基于类名、实现的接口以及所有公共和受保护的成员生成的。以任何方式更改任何这些都将更改serialVersionUID。因此,只有当您确定不会有多个版本的类被串行化(跨进程或稍后从存储中检索)时,才不需要使用它们。
如果您现在忽略它们,然后发现需要以某种方式更改类,但保持与旧版本类的兼容性,则可以使用JDK工具serialver在旧类上生成serialVersionUID,并在新类上显式设置。(根据您的更改,您可能还需要通过添加writeObject和readObject方法来实现自定义序列化-请参阅Serializable javadoc或上述第10章。)