如果更改 Java 异常类扩展的基类,是否需要更新serialVersionUID 值?
考虑以下 Java 异常类:
public class BarException extends RuntimeException {
// [...]
}
public class FooException extends BarException {
private static final long serialVersionUID = -5322002268075295537L;
// [...]
}
如果我希望更新继承层次结构以删除 BarException
,以便 FooException
直接从 RuntimeException
派生,请执行以下操作需要更改 serialVersionUID
值吗?
// FooException with updated inheritance hierarchy
public class FooException extends RuntimeException {
private static final long serialVersionUID = ???;
// [...]
}
Consider the following Java exception classes:
public class BarException extends RuntimeException {
// [...]
}
public class FooException extends BarException {
private static final long serialVersionUID = -5322002268075295537L;
// [...]
}
If I wish to update the inheritance hierarchy to remove BarException
, such that FooException
derives directly from RuntimeException
, does this require a change to the serialVersionUID
value?
// FooException with updated inheritance hierarchy
public class FooException extends RuntimeException {
private static final long serialVersionUID = ???;
// [...]
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的。根据 序列化规范。
Yes. "Moving classes up or down the hierarchy" will cause incompatibility with previous serialized instances, as per the serialization spec.
Java 1.5 序列化规范 表明从继承层次结构中删除类是一个兼容的更改,因此不需要对
serialVersionUID
进行更改。当反序列化为新的
FooException
(直接从RuntimeException
派生)时,序列化流中与BarException
有关的任何额外信息都将被忽略。The Java 1.5 Serialization Specification suggests that removing classes from the inheritance hierarchy is a compatible change, so a change to
serialVersionUID
should not be required.Any extra information in the serialization stream pertaining to
BarException
would be ignored when deserializing to the newFooException
(which is derived directly fromRuntimeException
).鉴于该规范不够清晰,足以引起混乱和争论,并且没有明确的答案出现,剩下的唯一选择就是相信经验证据。
以上述问题为例,
FooException
派生自BarException
,派生自RuntimeException
,然后从BarException
中删除在继承链中,我整理了一个示例应用程序来尝试各种组合的序列化和反序列化。我得到以下结果:
只要保持
serialVersionUID
不变,我就可以成功地将原始FooException
序列化和反序列化为更新后的FooException,反之亦然。
以下注意事项适用:
FooException
具有int
和Exception
类型的成员,已成功反序列化。BarException
没有向RuntimeException
添加任何其他成员。Given that the specification is unclear enough to cause confusion and debate, with no clear answer emerging, the only option left is to trust empirical evidence.
Taking the examples from the question above, of
FooException
deriving fromBarException
deriving fromRuntimeException
, and then removingBarException
from the inheritance chain, I put together a sample application to try serialization and de-serialization in various combinations.I get the following results:
As long as I keep the
serialVersionUID
unchanged, I can successfully serialize and deserialize the originalFooException
as the updatedFooException
, and vice versa.The following caveats apply:
FooException
has members of typeint
andException
, which are successfully deserialized.BarException
adds no additional members toRuntimeException
.从技术上讲是可以的,但这取决于您的系统是否保留序列化对象以及您是否控制新的重构代码的部署方式。
如果您不进行持久化,并且将使用新版本的代码刷新整个部署,我认为不需要更改
serialVersionUID
。Technically yes, but it depends on whether your system persists serialized objects and if you control how the new, refactored code is deployed.
If you don't do persistence and you will refresh the entire deployment with the new version of the code, I don't see the need to change the
serialVersionUID
.