列挙型 (enum type)
https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#jls-8.9
クラス型の特殊な1つ。型自身のstatic
インスタンスをまとめて保持する。switch
文の条件式に使用可能。
型の定義
{クラス修飾子} enum 型識別子 [親インターフェース] {
列挙定数リスト;
クラス本体定義
}
abstract
とfinal
は付けられない。
クラス本体定義を持つ列挙定数が1つ以上含まない限りは、暗黙的にfinal
になる。
入れ子列挙型は暗黙的にstatic
。
インスタンス化は自身の定義ブロック内での列挙定数としてのみ可能。(i.e. 外部でも内部でもnew
でインスタンス化できない。同一のインスタンスが1つしかないことが保証されていて、そのようなインスタンスをシングルトンインスタンスと言う)
インターフェース実装はできるが、クラス継承はできない。
列挙型E
の直の親クラスはEnum<E>
コンストラクタは暗黙的にprivate
となる。public
,protected
をつけるとコンパイルエラー 。
列挙定数
識別子 [(引数リスト)] [{クラス本体}]
自身の列挙型インスタンスを参照するもの。public static final
になる。
識別子は大文字で書くことが多い。
(引数リスト)
を書くと、クラス本体定義に定義したコンストラクタに渡せる。
クラス本体
を書くと、無名クラスと同様に継承ローカルクラスのインスタンス化となる。
上の列挙定数の定義は
public static final 列挙型名 識別子 = new 列挙型名([引数リスト]) [クラス本体];
と似たようなものである。前述のようにnew
によるインスタンス化はできないし、toString()
などObject
メソッドのオーバーライドとかも必要。
使用例
import java.time.DayOfWeek; public class EnumType { public static void main(String[] arg) { Direction d = Direction.EAST; System.out.println(d.getClass()); // class main.java.tutorial.Direction System.out.println(d); // EAST // Direction d1 = new Direction(); エラー。外部でインスタンス化できない。 Enum<Direction> superDire = d; // Directionの親クラス。 Object objDire = d; // Object は更に親。 // values()メソッドは列挙定数の配列を返す for (Direction d1 : Direction.values()){ System.out.print(d1 + " "); // NORTH SOUTH EAST WEST } System.out.println(); switch (d) { case EAST: System.out.println("EAST"); break; case WEST: System.out.println("WEST"); break; case NORTH: System.out.println("NORTH"); break; case SOUTH: System.out.println("SOUTH"); break; } // EAST E1 e = E1.C1; System.out.println(e.x); // 1 e.x = 0; System.out.println(E1.C1.x); // 0 e.f(); // a System.out.println(E1.C2); // C2 System.out.println(E1.C2.x); // 2 System.out.println(E1.C3.x); // 4 E1.C3.f(); // b Days day = Days.MONDAY; // 入れ子列挙型も暗黙的にstaticなので呼べる。 // APIにある列挙型の例 DayOfWeek d1 = DayOfWeek.FRIDAY; System.out.println(d1.plus(100)); // SUNDAY System.out.println(DayOfWeek.of(2)); // TUESDAY } enum Days { // 入れ子列挙型 SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } } enum Direction implements IF { NORTH, SOUTH, EAST, WEST // 列挙定数。Direction型インスタンスを参照している。 } enum E1 { C1(1), C2(2), // 引数を自身のコンストラクタに渡している。 C3(4) {// E1を継承した無名クラスのインスタンス化 @Override void f() { System.out.println("b"); } }; // public static final E1 C4 = new E1(4); //エラー。内部でもnewでインスタンス化できない。 int x; E1 (int x) { this.x = x; } void f() { System.out.println("a"); } } //enum E extends C {} エラー 。クラス継承はできない。 //enum E2 extends E1 {} エラー。列挙型の継承はできない。 interface IF {} class C {}