为什么在desialization时不使用用户定义的serialVersionUID?

时间:2013-11-17 07:08:42

标签: java serialization serialversionuid

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下添加了一个字段,即age。现在反序列化Employee2并获得以下错误

  

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

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

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

  

static final Long serialVersionUID = 1L;

3 个答案:

答案 0 :(得分:2)

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

static final long serialVersionUID = 1L;

只有在未明确且正确声明的情况下,UID才会在运行时动态计算。

请参阅Java Object Serialization Specification section 4.6

答案 1 :(得分:1)

再看一遍。 'long'与'long'不同,1L与-342194960183674221L不同,这是流中的内容。

答案 2 :(得分:0)

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

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

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