[Java]serialVersionUIDの意味と付け方

Pocket

 JavaのserialVersionUIDについて、JDKのJavadocJavaオブジェクト直列化仕様に記載されている要点を自分が理解しやすいような表現で記述・検証してみた。

スポンサードリンク


serialVersionUIDとは

 オブジェクトを直列化(オブジェクトをファイルやDBなどに入出力するために必要な手続き)した際に、出力したオブジェクトがどのクラスを元に作成されたのかを検証するための番号。
 同一クラスであってもソースコードに変更が加えられた場合、既に出力されているオブジェクトと新しく出力しようとしているオブジェクトは同一のクラスを元に作成されたとは言えなくなる。よってクラスのバージョンを識別するための番号でもある。

オブジェクト直列化するクラスはjava.io.Serializableインタフェースを実装する必要がある。

 直列化を行うタイミングはwriteされた時。serialVersionUIDの検証のタイミングはオブジェクトの直列化復元時、つまりread時に行われる。検証により現在のserialVersionUIDと一致しなかった場合や、クラスのインスタンス変数などに変更が加えられた場合、InvalidClassExceptionが発生する。


Warnningが出るがserialVersionUIDを明示しなくても良いのか

 明示しなかった場合は自動的にserialVersionUIDが付けられるが、コンパイラの実装に依存しているらしいのでその動作を保証していない。明示しておいた方が無難というより個人利用のプログラムではないのなら付けるべきだと思うし、公式ドキュメントでもそのように強く推奨している。


serialVersionUIDの付け方

 値は適当でもOKだが、既存または過去に存在したIDと同一だと重複する可能性がある。
 serialverを使用すればクラスの状態(詳細はわからないけど引数にクラス名を渡しているので)から自動で一意のIDを生成してくれる。
 自分はeclipseを使用しているので、Warnningが出ている箇所にフォーカスを当てた際(もしくはクラス名を選択してCtrl + 1)に出てくる「生成シリアル・バージョンIDの追加」で生成している。


serialVersionUIDの更新

 ケースバイケース?下記リンク先で少し検証してみた結果、少なくとも変数の型を変更するとInvalidClassExceptionが発生した。つまり、任意の場所に格納している永続的なオブジェクトと、現行システムが生成しているオブジェクト(正確にはその元のクラス)とに不整合が出た場合。

 不整合があっても良いシステムならserialVersionUIDは適当でもいいのではと思うし・・・。
 不整合があっちゃまずいシステムなら厳密に管理したほうが良いだろうし・・・。

 まぁ稼働中のシステムの変数名を変えるなんてレアケースだろうけど、他の予期しないケースもありえると思うので念には念を入れて自分なら更新しますかね・・・。


興味本意な検証をしてみた

→→serialVersionUIDのテスト


2014/10/8 リンク切れを修正しました

お役に立てましたか?

ブックマークをどうぞ!

スポンサード リンク

コメントを残す