考虑以下Java异常类:
public class BarException extends RuntimeException {
// [...]
}
public class FooException extends BarException {
private static final long serialVersionUID = -5322002268075295537L;
// [...]
}
如果我希望更新继承层次结构以删除BarException
,FooException
直接从RuntimeException
派生,这是否需要更改serialVersionUID
值?< / p>
// FooException with updated inheritance hierarchy
public class FooException extends RuntimeException {
private static final long serialVersionUID = ???;
// [...]
}
答案 0 :(得分:5)
是。根据{{3}},“在层次结构中向上或向下移动类”将导致与先前序列化实例不兼容。
答案 1 :(得分:2)
Java 1.5 Serialization Specification建议从继承层次结构中删除类是兼容的更改,因此不需要更改serialVersionUID
。
在反序列化为新BarException
(直接来自FooException
)时,将忽略序列化流中与RuntimeException
相关的任何额外信息。
答案 2 :(得分:2)
鉴于规范不够清晰,不足以引起混淆和辩论,没有明确的答案,唯一的选择就是信任经验证据。
根据上面问题中的示例,FooException
派生自BarException
派生自RuntimeException
,然后从继承链中删除BarException
,我将样本放在一起应用程序以各种组合尝试序列化和反序列化。
我得到以下结果:
只要我保持serialVersionUID
不变,我就可以成功序列化和反序列化原始FooException
作为更新的FooException
,和副反之亦然。强>
以下警告适用:
FooException
包含int
和Exception
类型的成员,这些成员已成功反序列化。BarException
不会向RuntimeException
添加任何其他成员。答案 3 :(得分:0)
技术上是,但这取决于您的系统是否持久化序列化对象以及您是否控制如何部署新的重构代码。
如果您没有执行持久性,并且您将使用新版本的代码刷新整个部署,我认为不需要更改serialVersionUID
。