特にテーマは無く雑記かな。 最近は自分用メモが増えてきましたけど。
スポンサーサイト
--年--月--日 (--) | 編集 |
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


Java の Serializable と serialVersionUID
2010年05月08日 (土) | 編集 |
JavaのSerializableのお話です。

シリアライズ可能なクラスの継承クラスを作成した時に、eclipseから serialVersionUID を設定するようにと注意されます。
よく意味が分からず、
  private static final long serialVersionUID = 1L;
と設定して凌いでいたりしました。

今までシリアライズを行う事も無かったのでこれで良かったのですが、やっぱり理解しておくべきかなぁと思って色々見たりしていました。
そんな話です。

 
そもそもシリアライズというのは、データを丸ごと保存とか通信とかできるよう変換すること。
データと書きましたが、Javaではクラスがこれに相当します。
シリアライズ可能なクラスは、丸ごとファイルとして保存したり、読み込んで復元することができる訳ですね。

クラスがシリアライズ可能であるには、Serializableが実装されており、フィールドの値が基本型かシリアライズ可能なクラスである必要があるようです。

さらに、最初は分かりづらい所として、
シリアライズ可能でないクラスを継承しつつSerializableが実装されたクラスでは、親クラスが引数なしのコンストラクタを持つ必要があるようです。ただし、この場合は親クラスのフィールドの値までは復元されません。

Serializable のJavadocはこれ。
Serializable (Java Platform SE 6)
オーバーライドすべきメソッドはありません。
Cloneable などと同じ扱いです。マーカーインターフェースというやつです。


本題の serialVersionUID は、保存したクラスを復元する際に、間違ったクラスとして復元するのを防止するためのもの。

例えばファイルに保存し、復元することを考えます。
保存する際には、保存するクラスが持っている serialVersionUID を一緒に保存しておきます。
復元する際には、復元するクラスが持っている serialVersionUID と、保存されている serialVersionUID を比べて、一緒じゃない場合にはエラーを出すことで誤りを防止するのです。

つまり serialVersionUID は、唯一の値(とりあえず他と被らなそうな値)であれば良さそうです。

この辺りの話は、
serialVersionUIDについて | OKWave
が参考になりました。


ところで、もし Serializable を実装しているのにも関わらず serialVersionUID が設定されていない場合はどうなるかというと、クラスの構造に応じて自動で生成されます。
もし明示的に serialVersionUID が設定されている場合は、設定された値が使用されます。
なら serialVersionUID は要らないのではと思う所ですが JavaVM の実装の違いで自動で生成される serialVersionUID が異なってしまうことがありえるようです。
またクラス構造が変わっても互換性が無いとは限らないので、管理できるのであれば serialVersionUID を設定した方が良さそうです。

結局 serialVersionUID の扱いは、
これからまだまだクラスの構造が変わる可能性がある場合には serialVersionUID は書かずに @SuppressWarnings("serial") で警告を消しておくのが良さそうです。
シリアライズを行わないつもりであれば serialVersionUID = 1L; でも良さそうです。
リリースするような場合には serialVersionUID を書いておくのが良さそうです。
スポンサーサイト

コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。