如果更改 Java 异常类扩展的基类,是否需要更新serialVersionUID 值?

发布于 2024-08-04 21:04:34 字数 616 浏览 11 评论 0原文

考虑以下 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

明天过后 2024-08-11 21:04:34

是的。根据 序列化规范

Yes. "Moving classes up or down the hierarchy" will cause incompatibility with previous serialized instances, as per the serialization spec.

红衣飘飘貌似仙 2024-08-11 21:04:34

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 new FooException (which is derived directly from RuntimeException).

同尘 2024-08-11 21:04:34

鉴于该规范不够清晰,足以引起混乱和争论,并且没有明确的答案出现,剩下的唯一选择就是相信经验证据。

以上述问题为例,FooException 派生自 BarException,派生自 RuntimeException,然后从 BarException 中删除在继承链中,我整理了一个示例应用程序来尝试各种组合的序列化和反序列化。

我得到以下结果:

只要保持 serialVersionUID 不变,我就可以成功地将原始 FooException 序列化和反序列化为更新后的 FooException,反之亦然。

以下注意事项适用:

  • 我使用的是 JDK 1.5.0_07,并且尚未在任何其他版本上尝试过此操作。
  • FooException 具有 intException 类型的成员,已成功反序列化。
  • 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 from BarException deriving from RuntimeException, and then removing BarException 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 original FooException as the updated FooException, and vice versa.

The following caveats apply:

  • I am using JDK 1.5.0_07, and have not tried this on any other versions.
  • FooException has members of type int and Exception, which are successfully deserialized.
  • BarException adds no additional members to RuntimeException.
木有鱼丸 2024-08-11 21:04:34

从技术上讲是可以的,但这取决于您的系统是否保留序列化对象以及您是否控制新的重构代码的部署方式。

如果您不进行持久化,并且将使用新版本的代码刷新整个部署,我认为不需要更改 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文