Effective Javaを読むチャレンジ-項目31-

項目31 序数の代わりにインスタンスフィールドを使用する

前項が非常に長かったので、短い項目でほっとしてます。enumのordinal()メソッドについての話。

例えば本書のサンプルのように、enumの数値位置(定数の並び順に対して先頭0から始まる番号を振ったもの)を返すordinal()メソッドを、定数と関連付けられた値として使用したい場合があるかもしれません。

本書のサンプルが保守に関して悪夢だという理由のなかで、まず定数の並び順を変えたら関連付ける値と序数との関係が破綻するのはすぐお分かりかと思います。その次の内容である8人構成から成るダブルカルテットのための定数を追加できないというのもすぐ分かりますね。この場合、関連付ける値を(1,2,3,4,5,6,7,8,8,9,10)となるように追加するしかないですが、序数は(0,1,2,3,4,5,6,7,8,9,10)という値にしかならないからです。

次の段落も簡単、飛び石のように値が離れるような定数は作れないという制限が発生します。関連付ける値が(1,3,5)だけでいいのに、序数は(0,1,2)となってしまい、関係が破綻するので、結局値を(1,2,3,4,5)、序数を(0,1,2,3,4)とし、本来不要な2と4の定数を作らなくてはなりません。これが100とか10000なら・・・やってられませんね。

というわけでordinal()メソッドを何かの値と関連付けるために使用せず、enum型のインスタンスフィールドにその値を保存してください、という結論になります。最終的にはordinalメソッドを全く使用しないのが最善としています。

最後の段落の「Enum仕様」というのは、java.lang.EnumのAPI仕様です。そのordinalメソッドの説明には「列挙定数の序数(列挙宣言での位置。初期定数はゼロの序数に割り当てられる)を返します。このメソッドは、ほとんどのプログラマにとって役に立ちません。EnumSetやEnumMapなどの高度なenumベースのデータ構造で使用するために設計されています。」とあります。

高度なenumベースのデータ構造というのはよく分かりませんが、後の項目でEnumMapについて出てくるので、それを見てという感じになるでしょうね。

広告
  • LINEで送る