SSブログ

enum定数とシリアライズ [Java]

書籍『Effective Java 第2版』では、項目3の最後にシングルトンを実装するためには、「現在ではシングルトンを実装する最善の方法は単一要素のenum型も用いることです。」と述べられています。特に、シリアライズ可能なシングルトンを実装するのであれば、そうです。そのため、項目77「インスタンス制御に対しては、readResolveよりenum型を選ぶ」と独立した項目も書かれています。

項目77のp.300には次のようにも述べられています。
enumとしてシリアライズ可能なインスタンス制御されたクラスを書くのであれば、宣言された定数の他にインスタンスが存在しないという完全な保証を得ます。JVMがその保証を行いますし、みなさんはそれに頼ることができます。みなさんの方で特別なことは必要ありません。

シリアライズに関しては、enumは特別に扱われます。それに関しては、拙著『Java 2 Standard Edition 5.0 Tiger 拡張された言語仕様』の4.7節「enum定数のシリアライズ」で説明しています。

Java 2 Standard Edition 5.0 Tiger―拡張された言語仕様について

Java 2 Standard Edition 5.0 Tiger―拡張された言語仕様について

  • 作者: 柴田 芳樹
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2005/04
  • メディア: 単行本


4.7節は短いので、その全文は以下の通りです。
java.lang.Enumクラスは、Serializableインタフェースを実装していますが、readResolveメソッドは定義されていません。従来のタイプセーフenumでは、readResolveメソッドを実装しなければ、正しくディシリアライズできませんでした。

リリース5.0からは、シリアライズ/ディシリアライズの仕様が変更になっており、enum定数は特別に処理されるようになっています。enum定数をシリアライズする場合には、nameフィールドだけがシリアライズされます。他のフィールドは一切シリアライズされません。そして、ディシリアライズでは、nameフィールドの値を用いて、Enum.valueOfメソッドを使用して値オブジェクトを取得するようになります。

enum型の宣言で、シリアライズ/ディシリアライズのためのカスタマイズ用メソッド(writeObjectreadObjectreadObjectNoDatawriteReplacereadResolve)を定義しても、すべて無視されます。同様に、serialPersistentFieldsserialVersionUIDもすべて無視され、serialVersionUIDは、常に0Lとなります。


拙著ではリリース1.5で導入された言語仕様に関する制限事項や、どのように実装されているかについて説明しています。ただし、私自身の用語に対する勘違いなどの誤りがありますので、参考にされる際には、正誤表も参照をお願いします。

『Java 2 Standard Edition 5.0 Tiger』正誤表
http://www001.upp.so-net.ne.jp/yshibata/tigererrata.html

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Facebook コメント

トラックバック 0