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

时间:2009-09-14 11:23:39

标签: java exception serialization serialversionuid

考虑以下Java异常类:

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

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

    // [...]
}

如果我希望更新继承层次结构以删除BarExceptionFooException直接从RuntimeException派生,这是否需要更改serialVersionUID值?< / p>

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

    // [...]
}

4 个答案:

答案 0 :(得分:5)

是。根据{{​​3}},“在层次结构中向上或向下移动类”将导致与先前序列化实例不兼容。

答案 1 :(得分:2)

Java 1.5 Serialization Specification建议从继承层次结构中删除类是兼容的更改,因此不需要更改serialVersionUID

在反序列化为新BarException(直接来自FooException)时,将忽略序列化流中与RuntimeException相关的任何额外信息。

答案 2 :(得分:2)

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

根据上面问题中的示例,FooException派生自BarException派生自RuntimeException,然后从继承链中删除BarException,我将样本放在一起应用程序以各种组合尝试序列化和反序列化。

我得到以下结果:

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

以下警告适用:

  • 我使用的是JDK 1.5.0_07,并且没有在任何其他版本上试过这个。
  • FooException包含intException类型的成员,这些成员已成功反序列化。
  • BarException不会向RuntimeException添加任何其他成员。

答案 3 :(得分:0)

技术上是,但这取决于您的系统是否持久化序列化对象以及您是否控制如何部署新的重构代码。

如果您没有执行持久性,并且您将使用新版本的代码刷新整个部署,我认为不需要更改serialVersionUID