使用较新的serialVersionUID

时间:2015-08-12 10:44:54

标签: java classcastexception

我有一个类InvalidClassException,序列版本为id private static final serialVersionUID = -5086279873877116405L;。此类的serialVersionUID的旧值为-6871353730928221293L。

现在我得到了例外

java.io.InvalidClassException: com.navtech.kernel.flat.FlatValidationException; local class incompatible: stream classdesc serialVersionUID = -6871353730928221293, local class serialVersionUID = -5086279873877116405L.

这里错了。

3 个答案:

答案 0 :(得分:0)

这是可以预料的。 serialVersionUID用于区分同一Serializable类的不同版本。很可能有一个很好的理由来改变版本,它实际上不能作为新版本反序列化。

答案 1 :(得分:0)

当一个对象被序列化时,serialVersionUID会与其他内容一起序列化。

稍后,当反序列化时,将提取反序列化对象中的serialVersionUID,并将其与已加载类的serialVersionUID进行比较。

数字不匹配,所以此例外。

要解决此问题: - 在取消激活之前,使用新的serialVersionUID序列化类。

答案 2 :(得分:0)

Doc:

中指定的不兼容更改

对类的不兼容更改是那些无法保证互操作性的更改。在进化课程时可能发生的不兼容的变化是:

  • 删除字段 - 如果在类中删除某个字段,则写入的流将不包含其值。当流由较早的类读取时,该字段的值将设置为默认值,因为流中没有可用的值。但是,此默认值可能会对早期版本履行合同的能力产生不利影响。

  • 在层次结构中向上或向下移动类 - 由于流中的数据显示的顺序错误,因此无法允许这样做。

  • 将非静态字段更改为静态字段或非瞬态字段 瞬态 依赖于默认序列化时,此更改等同于从类中删除字段。 此类版本不会将该数据写入流中,因此早期版本的将无法读取该数据。与删除字段时一样,早期版本的字段将初始化为默认值,这可能导致类以意外方式失败。

  • 更改原始字段的声明类型 该类的每个版本都使用其声明的类型写入数据。尝试读取该字段的类的早期版本将失败,因为流中的数据类型与字段的类型不匹配。

  • 更改writeObject或readObject

    方法,以便它不再写入或读取默认字段数据或更改它,以便它尝试写入或在先前版本没有时读取它。默认字段数据必须始终显示或不显示在流中。

  • 将类从Serializable更改为Externalizable,反之亦然

    是一种不兼容的更改,因为流将包含与可用类的实现不兼容的数据。

  • 将类从非枚举类型更改为枚举类型,反之亦然

    因为流将包含与可用类的实现不兼容的数据。

  • 删除Serializable或Externalizable是不兼容的 变化

    因为在编写时它将不再提供该类旧版本所需的字段。

  • 添加writeReplace或readResolve方法

    如果行为产生的对象与该类的任何旧版本不兼容,则

    与类不兼容。

在您的情况下,有可能在移动类层次结构时遇到问题,因为当存在继承问题时,具有其自己的特定serialUID的类将不会在已生成的流中被覆盖。         强烈建议所有可序列化类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类细节高度敏感,这些细节可能因编译器实现而异,因此在反序列化期间可能导致意外的InvalidClassExceptions。 希望这有帮助!