JavaのEnum(列挙型)とは?特徴や基本的な使い方も紹介

「Javaの列挙型(Enum)ってどうやって使うの?」
「Enum(列挙型)を使うメリットや注意点について知りたい」
「Enum(列挙型)のメソッドの使い方についてマスターしたいな」

Enum(列挙型)とは、複数の定数をひとつにまとめておくことができる型のことを指します。

ただし、定数に変更が生じたときにはコードの書き換えが必要になるため、実装する前に列挙型で定義する必要があるかどうかを慎重に検討することが大切です。

本記事では、Javaの列挙型の特性、基本的な使用法、注意点についてサンプルコードを用いて詳しく説明します。ぜひ最後までをご覧ください。

Enumを活用する利点

Enum(列挙型)を使用することによる主な利点は、以下の3つです。

  • コードの可読性の向上
  • コードの保守性の向上
  • プログラムの安全性の向上

Enum(列挙型)を利用することで、コード内で使用される定数が何を意味しているのかが明確になります。

以下のswitch文の具体例を見ていきましょう。Enum(列挙型)の使い方は後ほど解説するので、雰囲気をつかめれば大丈夫です。



public class Test {
    public void printDayActivity(Day day) {
        switch (day) {
            case MONDAY:
                System.out.println("Meeting day.");
                break;
            case FRIDAY:
                System.out.println("Report submission day.");
                break;
            default:
                System.out.println("Regular work day.");
                break;
        }
    }
}

この例では、Day Enumを使って、曜日ごとの活動を出力しています。Enum(列挙型)を使うことで、「MONDAY」、「 FRIDAY」などの列挙子が何を表しているかが一目で分かり、コードが読みやすくなっていますね。

2つ目のメリットは、コードの保守性の向上です。Enum(列挙型)を使うことで、誤った値がプログラムに入り込むことを防ぐことができるため、バグのリスクを減らすことができます。

たとえば、曜日を表すEnum(列挙型)がない場合、誤って”Mondy”という誤った文字列を使用してしまうかもしれません。Enum(列挙型)を使用していれば、このようなミスはコンパイル時に検出され、修正が求められます。

3つ目は、プログラムの安全性の向上です。特定の値の集合の中でのみ操作を行うように制限することができるため、意図しない値がプログラムに渡されるのを防ぐことができます。

また、Enum型(列挙型)はコンパイル時に値を展開しないため、定数クラスが変更された場合に利用クラスを再コンパイルする必要がなくなり、値の不整合が発生するリスクが減少します。

Java Enumの基本的な使い方

Enum(列挙型)を定義する基本的な形式は非常にシンプルで、以下の通りです。


 ‘=public enum 列挙型名{
        列挙定数1,
        列挙定数2,
        (中略)
        列挙定数N
      };

列挙定数は通常、全て大文字で記述されます。以下のサンプルコードを見ていきましょう。

  
public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

この例では、「Day」という名前のEnumが定義されており、週の各曜日が列挙定数として設定されています。

JavaのEnum(列挙型)の基本的な使い方や活用方法に関して実践的なサンプルコードをもとにさらに理解を深めてみましょう。先に触れたEnumの基本構文を覚えていれば、理解しやすくなります。

定数としてのEnum活用

Enum(列挙型)は、特定のカテゴリに属する固定された値の集合を定義する際に使用されます。基本的なEnumの宣言は以下のようになります。


public enum Season {
    SPRING, SUMMER, AUTUMN, WINTER;
}

この例では、「Season」というEnumが定義されており、四季を表す四つの列挙定数(SPRING, SUMMER, AUTUMN, WINTER)が含まれています。これらは、Season型の変数に代入して使用できます。

Enum(列挙型)では、各列挙定数に特定の値を割り当てることもできます。これを行うには、Enum内にフィールドとコンストラクタを定義します。

以下のサンプルコードを見てください。


public enum Fruit {
    BANANA(0), ORANGE(1), APPLE(2);

    private final int id;

    private Fruit(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }
}

このコードでは、Fruit Enumに各果物に対応する数値IDが割り当てられています。コンストラクタを通じてこのIDを初期化し、それを取得するためのメソッドも設定されています。

以下は、文字列を割り当てる例です。


public enum Fruit {
    BANANA("Okinawa"), ORANGE("Ehime"), APPLE("Aomori");

    private final String origin;

    private Fruit(String origin) {
        this.origin = origin;
    }

    public String getOrigin() {
        return this.origin;
    }
}

ここでは、Fruit Enumの各列挙定数に果物の産地を文字列として割り当てています。これにより、果物の名前と産地を一緒に管理することが可能になります。

具体的な値の割り当てが可能であるため、プログラムの柔軟性が増すのが特徴です。

Enumを使った条件分岐

Enum(列挙型)を条件分岐に利用する際には、通常の変数と同様にswitch文やif文で処理を分けることができます。switch文を使用した例は以下の通りです。


public class TrafficControl {
    public void signalAction(TrafficLight light) {
        switch (light) {
            case RED:
                System.out.println("Stop");
                break;
            case YELLOW:
                System.out.println("Caution");
                break;
            case GREEN:
                System.out.println("Go");
                break;
        }
    }

    public static void main(String[] args) {
        TrafficControl control = new TrafficControl();
        control.signalAction(TrafficLight.RED);  // 出力:Stop
        control.signalAction(TrafficLight.GREEN); // 出力:Go
    }
}

この例では、TrafficLight Enumを用いて、信号の色に応じたアクションをswitch文で分岐しています。Enum(列挙型)を使用することで、switch文内の各caseが何を意味しているのかが明確になりますね。

if文を使った例は以下の通りです。


public class CoffeeShop {
    public void printCupSize(Size size) {
        if (size == Size.SMALL) {
            System.out.println("You have chosen a small size.");
        } else if (size == Size.MEDIUM) {
            System.out.println("You have chosen a medium size.");
        } else if (size == Size.LARGE) {
            System.out.println("You have chosen a large size.");
        }
    }

    public static void main(String[] args) {
        CoffeeShop shop = new CoffeeShop();
        shop.printCupSize(Size.MEDIUM);  // 出力: You have chosen a medium size.
    }
}

このプログラムでは、Size Enumを使用して、選択されたカップのサイズに応じて異なるメッセージを表示しています。if文を使用して、Enum(列挙型)の各値に応じたアクションを実行しているのがわかるでしょう。

Enum列挙型)は特定の値のみを持つことができるため、無効な値が入るリスクがありません。列挙型を使うことで、エラーの可能性が低減し、コードの可読性が高まります。

なお、次の記事ではJavaのswitch文について詳しく解説しています。条件分岐への理解を深めたい人は、ぜひ参考にしてください。

Javaのswitch文とは?switch-case文を使った条件分岐も解説

Java Enumの応用的な使い方

これまで、Enum(列挙型)の定数のつけ方や条件分岐に関して学んできました。実は、Enumを使用することで、特定の値のセットを定義し、それらの値を扱うことができます。
Enum(列挙型)の応用的な使い方として、メソッドに関して理解を深めていきましょう。

Enumの主要メソッド

Enum(列挙型)の機能をフルに活用するためにいくつかの便利なメソッドが用意されています。以下が主なメソッドです。

  • name()メソッド
  • valueOf()メソッド
  • ordinal()メソッド
  • values()メソッド

name()メソッドは、Enum定数の名前を取得するために非常に重要なメソッドです。Enum定数がプログラムコード中でどのように宣言されたか、つまりそのリテラルな名前を文字列(String)として返します。

name()メソッドは引数を取らず、単純にEnum定数の名前を文字列で返すだけです。以下のサンプルコードをみていきましょう。


public enum TrafficLight {
    RED, YELLOW, GREEN;
    
    public static void main(String[] args) {
        // 各Enum定数のname()メソッドを呼び出し、その名前を出力する
        System.out.println(TrafficLight.RED.name());    // 出力: RED
        System.out.println(TrafficLight.YELLOW.name()); // 出力: YELLOW
        System.out.println(TrafficLight.GREEN.name());  // 出力: GREEN
    }
}

上記の例では、RED, YELLOW, GREENという文字列をTrafficLight Enumとして定義し、各Enum定数のname()メソッドを呼び出しています。

name ()メソッドは、エラーが発生したときに、どのEnum定数が関連しているか、プログラムの動作を追跡するために、どのEnum定数が使用されているかをログに記録する場合に役立ちます。

valueOf()メソッド、ordinal()メソッド、values()メソッドはこの後詳しく解説していきますね。

valueOfメソッドで列挙子名を取得する方法

JavaのEnum(列挙型)には、特定の文字列から対応するEnum定数を取得するための便利なメソッドvalueOf()が用意されています。

valueOf()メソッドを使用すると、文字列をEnumの型に安全に変換できるため、外部のデータソースから値を受け取ったり、ユーザー入力をEnum型に変換したりする際に非常に役立ちます。

valueOf()メソッドの構文は以下の通りです。

EnumType.valueOf(String name)

nameはEnum定数の名前を表す文字列で、戻り値は指定された名前に一致するEnum定数になります。

まだ理解しづらいと思うので、サンプルコードを見ていきましょう。以下の例では、DayというEnum型を定義し、valueOf()メソッドを使用して特定の日を取得します。


public static void main(String[] args) {
    try {
        Day day = Day.valueOf("FUNDAY");
        System.out.println("The day is: " + day);
    } catch (IllegalArgumentException e) {
        System.out.println("Error: The specified day is not valid.");
    }
}

この例では、FUNDAYという存在しない日をvalueOf()で取得しようとしています。存在しないため、例外が発生し、エラーメッセージが表示されます。

Error: The specified day is not valid.

以下の例は、Fruit Enumを定義し、valueOf()メソッドを使用して特定のフルーツ名をEnum定数に変換する方法を示しています。


public class Main {
    public enum Fruit {
        BANANA, ORANGE, APPLE;
    }

    public static void main(String[] args) {
        String input = "ORANGE";
        try {
            Fruit fruit = Fruit.valueOf(input);
            System.out.println("Selected fruit is: " + fruit);
        } catch (IllegalArgumentException e) {
            System.out.println(input + " is not a valid fruit.");
        }
    }
}

このプログラムでは、”ORANGE”という文字列がFruit EnumのORANGE定数に正しく変換され、その結果がコンソールに表示されます。出力は以下のようになります。

Selected fruit is: ORANGE

valueOf()メソッドは、正確な列挙子名が提供された場合にのみEnum定数を返すため、プログラムの堅牢性を保ちながら、柔軟に外部データやユーザー入力をEnum型として扱うことができます。

Java Enumクラスの概要

JavaにおけるEnum(列挙型)は、関連する定数をグループ化して管理するための機能です。Enum(列挙型)を利用することで、コードの可読性が向上し、エラーの発生を減らすことができます。Enumクラスの概要を理解するために、フィールド変数、コンストラクタの定義、およびEnumの使用における注意点について理解を深めていきましょう。

なお、Javaの列挙型についてより詳しく知りたい人は次の記事を参考にしてください。

JavaのEnum(列挙型)とは?特徴や基本的な使い方も紹介

フィールド変数・コンストラクタの定義

Enum(列挙型)にフィールド変数とコンストラクタを定義することで、各列挙子(Enumの要素)に固有の属性を持たせることができます。

フィールド変数は、Enum内で各列挙子が持つデータを格納するための変数です。数値や文字列など、任意の型をフィールドとして定義することができます。

コンストラクタは、Enumが生成される際に各列挙子に特定の値を設定するために使用されるメソッドです。コンストラクタは通常、フィールド変数を初期化するために用いられます。

以下のサンプルコードを見てください。


public enum Color {
    RED("#FF0000"), GREEN("#00FF00"), BLUE("#0000FF");
    
    private final String code;  // フィールド変数の定義

    private Color(String code) {  // コンストラクタの定義
        this.code = code;
    }

    public String getCode() {
        return this.code;
    }
}

このColor Enumでは、各色が持つ色コードをフィールド変数として持ち、コンストラクタを通じて初期化されており、Color.RED.getCode()のようにして色のコードを取得できます。

なお、Javaの変数についてより詳しく知りたい人は次の記事を参考にしてください。

Javaの変数とは?宣言や初期化の方法も解説

Enumクラスのメソッド定義

Enumでは、定義したフィールドの値を外部から取得するためのメソッドを定義することができます。これは、フィールドの値を安全に読み取るための「ゲッター」として機能します。

Enumクラスにメソッドを定義することは、Enumの各要素に個別のロジックを追加する場合に特に有用です。Enumは単なる定数の集まりではなく、それぞれが特定の機能を持つオブジェクトとしての役割も果たすようになります。

以下のサンプルコードを見てください。


public enum Fruit {
    ORANGE("Ehime"),
    APPLE("Aomori"),
    MELON("Ibaraki");

    private final String origin;

    private Fruit(String origin) {
        this.origin = origin;
   }

    public String getOrigin() {
        return this.origin;
    }

    public static void main(String[] args) {
        for (Fruit fruit : Fruit.values()) {
            System.out.println(fruit.ordinal() + ":" + fruit.name() + "," + fruit.getOrigin());
        }
    }
}

このプログラムでは、values()メソッドでEnumのすべての要素をループし、ordinal()で順番、name()で名前、getOrigin()で産地を表示しています。出力は以下のようになります。


0:ORANGE,Ehime
1:APPLE,Aomori
2:MELON,Ibaraki

JavaのEnumを使用することで、単純な定数よりもはるかに複雑なロジックやデータ構造を管理できます。フィールドとコンストラクタを使用することで、各Enum列挙子に固有の属性を設定でき、メソッドを通じてこれらの属性を操作したり取得したりすることができるでしょう。

以下は、交通信号を表すTrafficLight Enumに、信号ごとの行動指示を返すメソッドを追加する例です。


public enum TrafficLight {
    RED {
        @Override
        public String getAction() {
            return "Stop";
        }
    },
    YELLOW {
        @Override
    public String getAction() {
            return "Caution";
        }
    },
    GREEN {
        @Override
        public String getAction() {
            return "Go";
        }
    };

    public abstract String getAction();  // 抽象メソッド定義
}

この例では、TrafficLight Enumの各要素がgetAction()メソッドを具体的に実装しています。Enumの強力な機能を示すもので、列挙子ごとに異なる振る舞いを定義することが可能です。

例えば、TrafficLight.RED.getAction()を呼び出すと”Stop”が返されるようになります。

Enumでメソッドを定義する利点は、メソッドを通じて振る舞いをカプセル化することで、コードの変更がそのメソッド内に限定され、影響を受ける範囲が小さくなります。また同じ振る舞いが必要な他の部分でEnumを再利用できるため、コードの重複を減らせる点もメリットです。

Enumの注意点

Enum(列挙型)を使う上で注意する点は以下の通りです。

  • Enumの不変性
  • Enumのインスタンス化の禁止
  • 定数の値としてのEnumの使用

1つ目のEnumの不変性に関して、Enumの列挙子は、作成後にその状態を変更できません。列挙子に関連付けられた値は、そのライフサイクル全体を通じて不変であるべきです。


public enum Color {
    RED, GREEN, BLUE;
}

上記のColor Enumでは、RED、GREEN、BLUEは一度定義されると変更できません。これらの値をプログラム内で変更しようとすると、コンパイルエラーになります。

2つ目のEnumのインスタンス化の禁止に関して、Enumはnewキーワードを使ってインスタンス化することはできません。これは、Enumのセキュリティと整合性を保つために重要です。

そのため、以下の例ではDay Enumをインスタンス化しようとするとコンパイルエラーが発生します。


public enum Day {
    MONDAY, TUESDAY, WEDNESDAY;
    
    private Day() {
        // コンストラクタは自動的にprivateです。
    }
}

// これはエラーになります
Day day = new Day();

3つ目の定数の値としてのEnumの使用に関しては、switch文など、Enumがサポートされている構文で使用してください。Enumはswitch文などで使用されることがよくありますが、Enumの各定数はcaseラベルで直接使用する必要があります。


public enum Season {
    SPRING, SUMMER, FALL, WINTER;
}

public class TestSeason {
    public void printSeason(Season season) {
        switch (season) {
            case SPRING:
                System.out.println("It's spring");
                break;
            case SUMMER:
                System.out.println("It's summer");
                break;
            case FALL:
                System.out.println("It's fall");
                break;
            case WINTER:
                System.out.println("It's winter");
                break;
        }
    }
}

この例では、Season Enumがswitch文で適切に使用されています。

JavaのEnumを効果的に使用するためには、その特性と制限を正しく理解することが重要です。

Javaプログラミングのスキルを活かして収入を増やすなら

なかには、副業での収入獲得やフリーランスへの独立を目的にJavaプログラミングのスキル習得に励んでいる人もいますよね。

ただ、身につけたスキルをどう収入UPに繋げればいいのか、イメージが湧かない人もいるはず。

そんな方は、ぜひフリーランスのミカタをご活用ください。

出典:フリーランスのミカタ

フリーランスのミカタは、平均単価80万円以上の案件を取り揃える、ITエンジニアに特化したフリーランスエージェントです。具体的には、次のような週3回からフルリモートで請け負える案件を豊富に掲載しています。

また希望年収や稼働時間だけでなく、扱うプログラミング言語などを細かく指定して案件を探せるため、自分にあう仕事を見つけやすいサイト仕様になっています。

ただし、上記のような案件は条件として2〜3年の実務経験が求められるケースが多いです。そのため、応募する際はどれくらいの経験が必要なのかを前もってチェックしておきましょう。

フリーランスのミカタを活用すれば、中・長期的な安定収入が得られる案件が見つかりますよ。

どんな案件が掲載されているか気になる人は、下のボタンから自分にあう案件を探してみてください。

まとめ

これまで、Enum(列挙型)とは何か、Javaの列挙型の特性や使い方について説明しました。

Enumは、関連する定数を一つのグループにまとめるために使用されます。例えば、四季や曜日、信号の色など、限定された数の選択肢を持つ場合にEnumが役立ちます。

JavaのEnumを適切に使用することで、プログラムの整理と整合性が向上し、保守が容易になるので積極的に使うようにしましょう。

まだまだ知識が浅く、Javaの他の処理に関しても基礎知識をつけたい!注意点や実践的な使い方を知りたい!という方もいるでしょう。

本記事ではプログラミングに関する多くの疑問を解決できるので、参考にしてみてくださいね。

なお、下の記事ではJavaのコンパイルについて詳しく解説しているので、よければ参考にしてください。

Javaのコンパイルとは?実行方法からjavacコマンドの基礎知識も紹介