abstractなSerializableクラスにもserialVersionUIDが必要な理由

EclipseではserialVersionUIDが明示されていないSerializableなクラスに警告が表示されますが、今までは具象クラスのみが対象でした。Eclipse 3.4ではそのポリシーが変わって、クラスがabstractな場合にも警告が表示されるようになっています。

Eclipseのこれまでの挙動のせいで、abstractなSerializableクラスにはserialVersionUIDが不要だと思い込んでいたんですが、それは間違いだったみたいです。

どうしてabstract classにもserialVersionUIDが必要なのかというと、具象クラスのデシリアライズ過程で、スーパークラスのserialVersionUIDもチェックされることが理由のようです。

以下、再現例です。

public abstract class Aaa implements Serializable {
    public void sayAaa() {
        System.out.println("Aaa");
    }
}

public class Bbb extends Aaa {
    private static final long serialVersionUID = 12345678L;
}

このようなクラスAaaとBbbがあったとして、

  1. Bbbのインスタンスシリアライズ
  2. Aaa#sayAaa()を削除して再コンパイル
  3. Bbbをデシリアライズ

とすると、デシリアライズの時点で、InvalidClassException: local class incompatibleがスローされます。

こうならないために、クラスにserialVersionUIDを付けるときは、親にも全部付けないと駄目だよという話でした。

  • 参考

203241 – [compiler] Missing warning when a serializable class without serialVersionUID is also abstract