enum定数とシリアライズ [Java]
書籍『Effective Java 第2版』では、項目3の最後にシングルトンを実装するためには、「現在ではシングルトンを実装する最善の方法は単一要素のenum型も用いることです。」と述べられています。特に、シリアライズ可能なシングルトンを実装するのであれば、そうです。そのため、項目77「インスタンス制御に対しては、
項目77のp.300には次のようにも述べられています。
シリアライズに関しては、enumは特別に扱われます。それに関しては、拙著『Java 2 Standard Edition 5.0 Tiger 拡張された言語仕様』の4.7節「
4.7節は短いので、その全文は以下の通りです。
拙著ではリリース1.5で導入された言語仕様に関する制限事項や、どのように実装されているかについて説明しています。ただし、私自身の用語に対する勘違いなどの誤りがありますので、参考にされる際には、正誤表も参照をお願いします。
『Java 2 Standard Edition 5.0 Tiger』正誤表
http://www001.upp.so-net.ne.jp/yshibata/tigererrata.html
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―拡張された言語仕様について
- 作者: 柴田 芳樹
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2005/04
- メディア: 単行本
4.7節は短いので、その全文は以下の通りです。
java.lang.Enum
クラスは、Serializable
インタフェースを実装していますが、readResolve
メソッドは定義されていません。従来のタイプセーフenumでは、readResolve
メソッドを実装しなければ、正しくディシリアライズできませんでした。
リリース5.0からは、シリアライズ/ディシリアライズの仕様が変更になっており、enum
定数は特別に処理されるようになっています。enum
定数をシリアライズする場合には、name
フィールドだけがシリアライズされます。他のフィールドは一切シリアライズされません。そして、ディシリアライズでは、name
フィールドの値を用いて、Enum.valueOf
メソッドを使用して値オブジェクトを取得するようになります。
enum
型の宣言で、シリアライズ/ディシリアライズのためのカスタマイズ用メソッド(writeObject
、readObject
、readObjectNoData
、writeReplace
、readResolve
)を定義しても、すべて無視されます。同様に、serialPersistentFields
とserialVersionUID
もすべて無視され、serialVersionUID
は、常に0L
となります。
拙著ではリリース1.5で導入された言語仕様に関する制限事項や、どのように実装されているかについて説明しています。ただし、私自身の用語に対する勘違いなどの誤りがありますので、参考にされる際には、正誤表も参照をお願いします。
『Java 2 Standard Edition 5.0 Tiger』正誤表
http://www001.upp.so-net.ne.jp/yshibata/tigererrata.html
2008-12-21 07:53
nice!(0)
コメント(0)
トラックバック(0)
コメント 0