Strutsで注意したいシリアライズについて。
Sessionに入れたオブジェクトはメモリからディスクに書き出される可能性がある。StrutsならばActionFormを継承して作ったクラスが該当する。よって、Serializableをimplementsしたほうがよい。
ActionFormのシリアライズ
ActionFormはJavaBeanですので、
サブクラスもJavaBean仕様を満たすようにSerializableを実装すべきです。
JavaのAPIではこんな感じ。
しかし、デフォルトの serialVersionUID の計算は、
クラスの詳細情報に大きく左右され、このクラスの詳細情報はさらに、
コンパイラの実装状況に依存しているので、
直列化復元時に予期しない InvalidClassException が発生する可能性があります。
このような問題を防ぐためにも、すべての直列化可能クラスが
serialVersionUID 値を明示的に宣言するように設定することを強くお勧めします。
というわけで、明示的に宣言すべき。serialVersionUIDはstatic finalのlong型、できるだけprivateらしい。
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
シリアライズ方法
Eclipse3.1からは警告が出ます。
シリアライズ可能クラス LoginFormはlong型のstatic final serialVersionUIDフィールドを宣言していません。
警告をクリックすると、どうするか聞いてくる。
そこで「生成シリアル・バージョンIDの追加」を選ぶと、するとEclipseが自動生成してくれる。
private static final long serialVersionUID = -1302472848604305617L;
EclipseはserialVersionUIDをどうやってつけているのか?
JDKには「serialver.exe」というものがあるらしく、これを使っているのではないかな?想像だが「クラス名のFQDN」&「全メソッド」&「変数」にハッシュか何かをかけてつけているぽい。
ただ、これだとすると、クラス名やメンバ変数などが変わるごとにserialVersionUIDを変えないといけないらしいので、最後の最後に付け直すのがいいみたい。
serialVersionUIDで何をしているのか?
面白い実験をしているサイト発見。
参考:昼間のメモさん
serialVersionUIDが同じだとしても、デシリアライズでClassCastExceptionが発生するため、気にしなくていいらしい。シリアル化したバイナリデータはクラス名や変数名も持っているので、かぶっても大丈夫だとのこと。