CodeGym /Java Blog /ランダム /JavaのEnumクラス
John Squirrels
レベル 41
San Francisco

JavaのEnumクラス

ランダム グループに公開済み
やあ!この記事では、 Java Enumについて説明します。次のタスクが与えられたと想像してください。曜日を実装するクラスを作成します。一見すると、これはかなり簡単に思えます。コードは次のようになります。
public class DayOfWeek {

   private String title;

   public DayOfWeek(String title) {
       this.title = title;
   }

   public static void main(String[] args) {
       DayOfWeek dayOfWeek = new DayOfWeek("Saturday");
       System.out.println(dayOfWeek);
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
すべてがうまくいっているように見えますが、問題が 1 つあります。それは、 DayOfWeekクラス のコンストラクターに任意のテキストを渡すことができるということです。つまり、誰かが「Frog」、「Cloud」、「azaza322」という名前の曜日を作成できるということです。実際の曜日は 7 つしかなく、それぞれに特定の名前があるため、これは明らかに予期した動作ではありません。したがって、私たちのタスクは、 DayOfWeekクラスの可能な値の範囲を何らかの方法で制限することです。Java 1.5 が登場する前は、この言語には既製のソリューションがなかったため、開発者はこの問題に対する独自のソリューションを独自に考案する必要がありました。当時、プログラマーは値の数を制限する必要がある場合、次のようにしていました。
public class DayOfWeek {

   private String title;

   private DayOfWeek(String title) {
       this.title = title;
   }

   public static DayOfWeek SUNDAY = new DayOfWeek("Sunday");
   public static DayOfWeek MONDAY = new DayOfWeek("Monday");
   public static DayOfWeek TUESDAY = new DayOfWeek("Tuesday");
   public static DayOfWeek WEDNESDAY = new DayOfWeek("Wednesday");
   public static DayOfWeek THURSDAY = new DayOfWeek("Thursday");
   public static DayOfWeek FRIDAY = new DayOfWeek("Friday");
   public static DayOfWeek SATURDAY = new DayOfWeek("Saturday");

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
注意すべき点は次のとおりです。
  • コンストラクターはプライベートです。コンストラクターがprivate修飾子でマークされている場合、それを使用してオブジェクトを作成することはできません。また、クラスにはコンストラクターが 1 つしかないため、DayOfWeekオブジェクトを作成することはできません。

    public class Main {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = new DayOfWeek(); // Error!
       		}
    }

  • もちろん、このクラスには、(正しい曜日名を使用して) 正しく初期化された、必要な数のパブリック静的オブジェクトが含まれています。

    これにより、これらのオブジェクトを他のクラスで使用できるようになりました。

    public class Person {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = DayOfWeek.SUNDAY;
    
           			System.out.println(sunday);
      		 }
    }

    出力:

    DayOfWeek{タイトル = '日曜日'}

このアプローチにより、問題は大幅に解決されます。私たちは自由に 7 つの曜日を設定できますが、誰も新しい曜日を作成することはできません。このソリューションは、Joshua Bloch 氏の著書『Effective Java』で提供されました。ちなみに、この本は非常に素晴らしく、Java 開発者にとって必読の本です。 Enumクラスの使い方 - 2Java 1.5 のリリースにより、この言語には、そのような状況に対する既製のソリューションであるJava Enumが追加されました。 Java の Enumもクラスです。このような問題を解決するために、つまり特定の限られた範囲の値を作成するために特別に「微調整」されています。Java の作成者はすでに準備ができたサンプルを持っていたので (たとえば、C にはすでにenumがありました)、最良のバリアントを作成することができました。

では、Java Enum とは何でしょうか?

DayOfWeekの例をもう一度見てみましょう。
public enum DayOfWeek {

   SUNDAY,
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY
}
これで、はるかに単純に見えます:) 内部的には、Enumには7 つの静的定数があります。そしてそれをプログラムの実装に使用できるのです。たとえば、生徒が今日学校に行く必要があるかどうかを判断するプログラムを書いてみましょう。学生にはStudentScheduleクラスで表される毎日のスケジュールがあります。
public class StudentSchedule {

   private DayOfWeek dayOfWeek;
   // ... other fields


   public DayOfWeek getDayOfWeek() {
       return dayOfWeek;
   }

   public void setDayOfWeek(DayOfWeek dayOfWeek) {
       this.dayOfWeek = dayOfWeek;
   }
}
スケジュール オブジェクトのdayOfWeek変数によって、今日が何日であるかが決まります。そして、これが私たちの学生クラスです:
public class Student {

   private StudentSchedule schedule;
   private boolean goToSchool;

   public void wakeUp() {

       if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
           System.out.println("Hooray, you can sleep more!");
       } else {
           System.out.println("Damn, time for school again :(");
       }
   }
}
wakeUp()メソッド では、 Java Enumを使用して生徒が次に何をすべきかを決定します。DayOfWeekの各フィールドの詳細さえ提供していませんし、その必要もありません。曜日がどのように機能するかは明らかです。現在の形式で使用すると、開発者はコード内で何が起こっているかを理解できるでしょう。Enumの便利さのもう 1 つの例は、その定数を switch ステートメントで使用できることです。たとえば、料理が日ごとにスケジュールされる、厳格な食事療法のためのプログラムを書いてみましょう。
public class VeryStrictDiet {
   public void takeLunch(DayOfWeek dayOfWeek) {
       switch (dayOfWeek) {
           case SUNDAY:
               System.out.println("Sunday Dinner! You can even enjoy something a little sweet today.");
               break;
           case MONDAY:
               System.out.println("Lunch for Monday: chicken noodle soup!");
               break;
           case TUESDAY:
               System.out.println("Tuesday, today it's celery soup :(");
               break;
               //... and so on to the end
       }
   }
}
これは、 Java 1.5 より前に使用されていた古いソリューションに対するEnum の利点の 1 つです。古いソリューションはswitchでは使用できませんでした。 Enumについて他に知っておくべきことは何ですか ? Enum は、これに伴うあらゆる可能性を備えた実際のクラスです。たとえば、現在の曜日の実装が不十分な場合は、変数、コンストラクター、およびメソッドをDayOfWeekに追加できます。
public enum DayOfWeek {

   SUNDAY ("Sunday"),
   MONDAY ("Monday"),
   TUESDAY ("Tuesday"),
   WEDNESDAY ("Wednesday"),
   THURSDAY ("Thursday"),
   FRIDAY ("Friday"),
   SATURDAY ("Saturday");

   private String title;

   DayOfWeek(String title) {
       this.title = title;
   }

   public String getTitle() {
       return title;
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
これで、Enum定数にはタイトルフィールド、ゲッター、およびオーバーライドされたtoStringメソッドが追加されました。 通常のクラスと比較すると、 Enumには継承できないというJava の Enum クラス - 2重大な制限が 1 つあります。さらに、列挙型には特徴的なメソッドがあります。
  • value() : Enum内のすべての値の配列を返します。

    public static void main(String[] args) {
       		System.out.println(Arrays.toString(DayOfWeek.values()));
    }

    出力:

    [DayOfWeek{title = '日曜日'}、DayOfWeek{title = '月曜日'}、DayOfWeek{title = '火曜日'}、DayOfWeek{title = '水曜日'}、DayOfWeek{title = '木曜日'}、DayOfWeek{title = '金曜日'}、DayOfWeek{title = '土曜日'}]

  • ordinal() : 定数の序数を返します。番号付けはゼロから始まります。

    public static void main(String[] args) {
    
       		int sundayIndex = DayOfWeek.SUNDAY.ordinal();
       		System.out.println(sundayIndex);
    }

    出力:

    0

  • valueOf() :渡された名前に対応するEnumオブジェクトを返します。

    public static void main(String[] args) {
       DayOfWeek sunday = DayOfWeek.valueOf("SUNDAY");
       System.out.println(sunday);
    }

    出力:

    DayOfWeek{タイトル = '日曜日'}

ノート:Enumフィールドを指定するには大文字を使用します。これらは定数であるため、キャメルケースではなくすべて大文字を使用します。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION