3

考虑以下 Java 异常类:

public class BarException extends RuntimeException {
    // [...]
}

public class FooException extends BarException {
    private static final long serialVersionUID = -5322002268075295537L;

    // [...]
}

如果我希望将继承层次结构更新为 remove BarException,例如FooException直接派生自RuntimeException,这是否需要更改serialVersionUID值?

// FooException with updated inheritance hierarchy
public class FooException extends RuntimeException {
    private static final long serialVersionUID = ???;

    // [...]
}
4

4 回答 4

5

是的。根据序列化规范,“将类向上或向下移动层次结构”将导致与以前的序列化实例不兼容。

于 2009-09-14T11:27:26.193 回答
2

Java 1.5 序列化规范建议从继承层次结构中删除类是一种兼容的更改,因此serialVersionUID不需要更改 。

反序列化到新的(直接派生自)时,序列化流中的任何额外信息都BarException将被忽略。FooExceptionRuntimeException

于 2009-09-14T11:26:34.760 回答
2

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

以上面问题中的例子,FooExceptionBarExceptionderiving from RuntimeException,然后BarException从继承链中删除,我整理了一个示例应用程序来尝试各种组合的序列化和反序列化。

我得到以下结果:

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

以下注意事项适用:

  • 我使用的是 JDK 1.5.0_07,并没有在任何其他版本上尝试过。
  • FooExceptionint具有and类型的成员Exception,它们已成功反序列化。
  • BarException不向 . 添加任何其他成员RuntimeException
于 2009-10-15T07:27:38.917 回答
0

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

如果你不做持久化,你会用新版本的代码刷新整个部署,我认为没有必要更改serialVersionUID.

于 2009-09-15T11:16:58.777 回答