0
public class Employee2 implements java.io.Serializable {


    private String name;

    public String getName() {
    return name;
}


public void setName(String name) {
    this.name = name;
}

}

我首先序列化了 Employee2 对象。然后在 Employee2 下又添加了一个字段,即年龄。现在反序列化 Employee2 并得到以下错误

java.io.InvalidClassException:Test.Employee2;本地类不兼容:流classdesc serialVersionUID = -342194960183674221,本地类serialVersionUID = -8890407383319808316

这是预期的,因为类的结构已被修改(因此 serialVersionUID 被修改,这是在序列化和反序列化时内部计算的)

现在,如果我在 Employee2 下声明以下字段并重复该场景,根据我的理解,我不应该得到 InvalidClassException,因为 serialVersionUID 在序列化和反序列化时是相同的,但我仍然得到 InvalidClassException 异常。为什么?如果序列化过程仍然使用在运行时计算的serialVersionUID,而不是在类下手动定义,那么声明它有什么用?

静态最终 Long serialVersionUID = 1L;

4

3 回答 3

2

您正在使用Long, 对象类型。您应该使用long原始类型,例如:

static final long serialVersionUID = 1L;

仅当未明确且正确声明 UID 时,它才会在运行时动态计算。

请参阅Java 对象序列化规范第 4.6 节

于 2013-11-17T07:13:29.193 回答
1

再看一遍。“Long”与“long”不同,1L 与流中的 -342194960183674221L 不同。

于 2013-11-17T07:13:18.073 回答
0

serialVersionUID 是其原始类的哈希。如果类被更新,例如使用不同的字段,serialVersionUID 可能会改变。您有四个(至少)可能的行动方案:

  1. 省略serialVersionUID。这告诉运行时在序列化和反序列化时类的版本之间没有差异。
  2. 总是写一个默认的serialVersionUID,它看起来像这个线程的标题。这告诉 JVM 具有此 serialVersionUID 的所有版本都算作同一版本。
  3. 从该类的先前版本复制一个 serialVersionUID。这告诉运行时这个版本和 SUID 来自的版本将被视为相同的版本。
  4. 为类的每个版本使用生成的 serialVersionUID。如果类的新版本中的 serialVersionUID 不同,则告诉运行时这两个版本不同,并且旧类的序列化实例不能反序列化为新类的实例。

资源 :

http://www.coderanch.com/t/596397/java/java/private-static-final-long-serialVersionUID

于 2013-11-17T07:21:48.633 回答