プログラミングの際、特定のデータ型に対して有効な値のセットを制限する必要が生じることがよくあります。したがって、たとえば、曜日には 7 つの異なる値を指定でき、月には 12 の異なる値を指定でき、季節には 4 つの異なる値を指定できます。このような問題を解決するために、多くの静的型付けプログラミング言語では特別なデータ型が提供されています。列挙 ( Enum メンバーは、
要素は、-class の
enum
)。列挙は Java にすぐには現れませんでした。特殊な言語構造がenum
バージョン 1.5 から導入されました。これまで、プログラマは他の方法を使用して列挙を実装してきました。
enum 構造体
例から始めましょう。enum
次を使用して、季節を保存するためのデータ型 を説明しましょう。
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
さて、その簡単な使用例:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
その結果、SUMMER がコンソールに出力されます。この例は明白で説明の必要はないと思います。
Enum はクラスです
を宣言することでenum
、 から派生したクラスを暗黙的に作成しますjava.lang.Enum
。enum Season { ... }
従来は と同等の構造となっておりますclass Season extends java.lang.Enum { ... }
。コンパイラでは明示的に継承することはできませんが、次のコマンドを使用して継承されているjava.lang.Enum
ことを簡単に確認できます。 enum
reflection
System.out.println(Season.class.getSuperclass());
コンソールに次のように表示されます。
class java.lang.Enum
実際の継承は、Java コンパイラによって自動的に実行されます。enum
次に、列挙型を実装するためにコンパイラによって作成されたクラスを-class と呼び、列挙型の取り得る値を -a 要素として呼び出すことに同意しますenum
。
Enum メンバーは、enum
静的にアクセスできる -class のインスタンスです。
要素は、-class のenum Season (WINTER, SPRING и т.д.)
静的にアクセス可能なインスタンスです。静的に利用できるため、参照比較演算子を使用して比較を実行できます。例: enum
Season
==
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;
enum 要素の名前とシリアル番号
前述したように、enum
-class はjava.lang.Enum
すべての列挙に役立つ多数のメソッドを含む を継承します。例:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
出力は次のようになります。
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
メソッドname()
とtoString()
をここに示しますordinal()
。メソッドのセマンティクスは明らかです。enum
これらのメソッドはクラスから継承されることに注意してくださいjava.lang.Enum
。 名前の文字列表現によって要素を取得するenum
enum
多くの場合、文字列表現によって要素を取得するタスクが発生します。これらの目的のために、enum
コンパイラは各 -class で特別な静的メソッド を自動的に作成します。このメソッドは、と等しい名前を持つpublic static EnumClass valueOf(String name)
列挙要素を返します。使用例: EnumClass
name
String name = "WINTER";
Season season = Season.valueOf(name);
コードを実行した結果、season 変数は と等しくなりますSeason.WINTER
。要素が見つからない場合はIllegalArgumentException がスローされ、要素がname
等しい場合null
はNullPointerExceptionがスローされることに注意してください。ところで、これはよく忘れられます。何らかの理由で、多くの人は、関数が 1 つの引数を取り、特定の条件下でIllegalArgumentExceptionをスローする場合、そこに関数を渡すとnull
必ずIllegalArgumentExceptionもスローされると確信しています。しかし、それは問題ではありません。続けましょう。 列挙型のすべての要素のenum
取得 実行時に -class の すべての要素のリストを取得する必要がある場合があります。これらの目的のために、enum
コンパイラは各 -class にメソッドを作成しますpublic static EnumClass[] values()
。使用例:
System.out.println(Arrays.toString(Season.values()));
次の出力が得られます。
[WINTER, SPRING, SUMMER, AUTUMN]
メソッドvalueOf()
もメソッドもvalues()
クラス内に定義されていないことに注意してくださいjava.lang.Enum
。enum
代わりに、 -class のコンパイル 時にコンパイラによって自動的に追加されます。-classへの独自のメソッドの追加enum
enum
-class とその要素の 両方に独自のメソッドを追加することができます。同じですが、ポリモーフィズムがあります。 最後の例は、 での継承の使用を示していますenum
。これについては後で詳しく説明します。 Javaの継承をenum
enum
使用すると、クラス階層を実装できます。クラス階層のオブジェクトは単一のインスタンスで作成され、静的にアクセスできます。この場合、要素にはenum
独自のコンストラクターを含めることができます。例を挙げてみましょう。 ここでは、と の3 つの要素を持つ列挙を宣言します。コンパイラは次のクラスとオブジェクトを作成します。 Type
INT
INTEGER
STRING
Type
- から派生したクラスjava.lang.Enum
INT
— から派生した第 1 クラスのオブジェクトType
INTEGER
— から派生した 2 番目のクラスのオブジェクトType
STRING
— から派生した 3 番目のクラスのオブジェクトType
Object parse(String)
とコンストラクターを使用して 3 つの派生クラスが作成されますType(..., boolean)
。同時に、 クラス 、およびのオブジェクトは単一のコピーに存在し、静的にアクセスできますINT
。これは次のように確認できます。 INTEGER
STRING
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass() + " " + Type.STRING.getClass().getSuperclass());
次の出力が得られます。
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
Type
コンパイラが 1 つのクラスとnested
から派生した 3 つのクラス を作成したことがわかりますType
。
逆コンパイルされた enum-class と継承
Type
上記を確認するために、上記の例から 列挙を逆コンパイルした結果も示します。
列挙とパラメトリック多態性
読者は「なぜ上記の Type 列挙型はジェネリックスを使用しないのですか?」と疑問に思うかもしれません。実際のところ、Java ではジェネリックスの使用はenum
禁止されています。したがって、次の例はコンパイルされません。
enum Type<T> {}
さらなる研究
Java で列挙がどのように機能するかをより深く理解するには、 クラス のソース コードをよく理解しjava.lang.Enum
、Jad デコンパイラーを使用して生成されたコードを調べることをお勧めします。さらに、Java ライブラリのソース コードを学習することは、Java のメカニズムがどのように機能するかを理解するために絶対に必要であり、オブジェクト指向設計の参考としても役立ちます。元のソースへのリンク: http://alexander.lds.lg.ua/
GO TO FULL VERSION