JavaRush /Java Blog /Random-JA /Java の列挙型 (java enum)
articles
レベル 15

Java の列挙型 (java enum)

Random-JA グループに公開済み
プログラミングの際、特定のデータ型に対して有効な値のセットを制限する必要が生じることがよくあります。したがって、たとえば、曜日には 7 つの異なる値を指定でき、月には 12 の異なる値を指定でき、季節には 4 つの異なる値を指定できます。このような問題を解決するために、多くの静的型付けプログラミング言語では特別なデータ型が提供されています。列挙 ( enum)。列挙は Java にすぐには現れませんでした。特殊な言語構造がenumバージョン 1.5 から導入されました。これまで、プログラマは他の方法を使用して列挙を実装してきました。 Java の列挙型 (java enum) - 1

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.Enumenum Season { ... }従来は と同等の構造となっておりますclass Season extends java.lang.Enum { ... }。コンパイラでは明示的に継承することはできませんが、次のコマンドを使用して継承されているjava.lang.Enumことを簡単に確認できます。 enumreflection
System.out.println(Season.class.getSuperclass());
コンソールに次のように表示されます。
class java.lang.Enum
実際の継承は、Java コンパイラによって自動的に実行されます。enum次に、列挙型を実装するためにコンパイラによって作成されたクラスを-class と呼び、列挙型の取り得る値を -a 要素として呼び出すことに同意しますenum

Enum メンバーは、enum静的にアクセスできる -class のインスタンスです。

要素は、-class のenum Season (WINTER, SPRING и т.д.)静的にアクセス可能なインスタンスです。静的に利用できるため、参照比較演算子を使用して比較を実行できます。例: enumSeason==
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名前の文字列表現によって要素を取得するenumenum多くの場合、文字列表現によって要素を取得するタスクが発生します。これらの目的のために、enumコンパイラは各 -class で特別な静的メソッド を自動的に作成します。このメソッドは、と等しい名前を持つpublic static EnumClass valueOf(String name)列挙要素を返します。使用例: EnumClassname
String name = "WINTER";
Season season = Season.valueOf(name);
コードを実行した結果、season 変数は と等しくなりますSeason.WINTER。要素が見つからない場合はIllegalArgumentException がスローされ、要素がname等しい場合nullNullPointerExceptionがスローされることに注意してください。ところで、これはよく忘れられます。何らかの理由で、多くの人は、関数が 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.Enumenum代わりに、 -class のコンパイル 時にコンパイラによって自動的に追加されます。-classへの独自のメソッドの追加enumenum-class とその要素の 両方に独自のメソッドを追加することができます。Java の列挙型 (java enum) - 2同じですが、ポリモーフィズムがあります。 Java の列挙型 (java enum) - 3最後の例は、 での継承の使用を示していますenum。これについては後で詳しく説明します。 Javaの継承をenumenum使用すると、クラス階層を実装できます。クラス階層のオブジェクトは単一のインスタンスで作成され、静的にアクセスできます。この場合、要素にはenum独自のコンストラクターを含めることができます。例を挙げてみましょう。 ここでは、と の3 つの要素を持つJava の列挙型 (java enum) - 4列挙を宣言します。コンパイラは次のクラスとオブジェクトを作成します。 TypeINTINTEGERSTRING
  • Type- から派生したクラスjava.lang.Enum
  • INT— から派生した第 1 クラスのオブジェクトType
  • INTEGER— から派生した 2 番目のクラスのオブジェクトType
  • STRING— から派生した 3 番目のクラスのオブジェクトType
多態性メソッドObject parse(String)とコンストラクターを使用して 3 つの派生クラスが作成されますType(..., boolean)。同時に、 クラス 、およびのオブジェクトは単一のコピーに存在し、静的にアクセスできますINT。これは次のように確認できます。 INTEGERSTRING
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上記を確認するために、上記の例から 列挙を逆コンパイルした結果も示します。Java の列挙型 (java enum) - 5

列挙とパラメトリック多態性

読者は「なぜ上記の Type 列挙型はジェネリックスを使用しないのですか?」と疑問に思うかもしれません。実際のところ、Java ではジェネリックスの使用はenum禁止されています。したがって、次の例はコンパイルされません。
enum Type<T> {}

さらなる研究

Java で列挙がどのように機能するかをより深く理解するには、 クラス のソース コードをよく理解しjava.lang.Enum、Jad デコンパイラーを使用して生成されたコードを調べることをお勧めします。さらに、Java ライブラリのソース コードを学習することは、Java のメカニズムがどのように機能するかを理解するために絶対に必要であり、オブジェクト指向設計の参考としても役立ちます。元のソースへのリンク: http://alexander.lds.lg.ua/
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION