我有一个类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.
这里错了。
答案 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。 希望这有帮助!