列挙型(Enum)で定数をスマートにまとめよう

docs

前回の記事では、Javaの「定数」について学んだね。finalキーワードを使って、一度初期化したら変更できない値を定義するんだった。今回は、その定数をさらに便利に、そして安全に管理するための強力な仕組み「列挙型(Enum)」について解説していくよ!

finalキーワードで「変更できない」を宣言しよう | ToolDocs

Enumってなに?

Enumは「Enumeration(列挙)」の略で、関連する定数をひとつのグループにまとめて定義できる特殊なクラスなんだ。例えば、曜日、月、信号の色など、決まった選択肢しかないものを扱うときにすごく便利。

イメージとしては、今までバラバラに定義していた定数たちを、同じ箱の中にまとめて整理するような感じかな。

Java

// Enumを使わない場合
public static final int SUNDAY = 0;
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
// ...と延々と続く

// Enumを使う場合
public enum DayOfWeek {
    SUNDAY,
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY
}

どう?すごくスッキリしたと思わない?

Enumを使うメリット

Enumを使うと、こんなに良いことがあるんだ。

  • タイプセーフ(型安全)になる 例えば、曜日を表すのにint型を使っていたら、DayOfWeekには存在しない99なんて数字も入れられちゃう可能性があるよね。でもEnumなら、定義された定数しか使えないから、そんな心配はないんだ。これが「型安全」ってこと。間違った値を設定することを防いでくれるんだよ。
  • コードが読みやすくなる SUNDAYって書くのと0って書くのでは、どっちが何を意味しているか分かりやすい?もちろんSUNDAYだよね。Enumを使うと、コードがより直感的になって、他の人が見ても「あ、これは曜日を表してるんだな」ってすぐに理解できるようになるんだ。
  • 変更に強くなる もし途中で定数の値を変えたいってなっても、Enumなら影響範囲が少ないんだ。例えば、MONDAYの内部的な値を1から10に変更しても、Enumを使っている場所では変更せずに済むことが多いんだよ。

Enumの基本的な使い方

じゃあ、実際にEnumをどうやって使うのか見ていこう。

1. Enumの定義

Enumはenumキーワードを使って定義するよ。定数名は大文字で書くのが一般的だ。

Java

public enum Season {
    SPRING,  // 春
    SUMMER,  // 夏
    AUTUMN,  // 秋
    WINTER   // 冬
}

2. Enumの利用

定義したEnumは、他の型と同じように変数に代入したり、メソッドの引数に使ったりできるよ。

Java

public class EnumExample {
    public static void main(String[] args) {
        Season currentSeason = Season.SUMMER; // 夏を代入

        if (currentSeason == Season.SUMMER) { // == で比較できる
            System.out.println("今は夏です!");
        }

        // switch文でも使える!これがEnumの真骨頂!
        switch (currentSeason) {
            case SPRING:
                System.out.println("桜が咲く季節!");
                break;
            case SUMMER:
                System.out.println("海で泳ぎたい季節!");
                break;
            case AUTUMN:
                System.out.println("紅葉がきれいな季節!");
                break;
            case WINTER:
                System.out.println("雪遊びが楽しい季節!");
                break;
        }
    }
}

switch文でEnumを使うと、すごくスッキリ書けるのがわかるかな?それぞれのcaseにEnumの定数を指定するだけでOKなんだ。

vscodeで実行した結果

Enumに値やメソッドを追加する

Enumはただの定数の集まりじゃないんだ。実は、フィールド(変数)やコンストラクタ、メソッドも持たせることができる、かなり高機能な「クラス」なんだよ。

例えば、それぞれの季節に「平均気温」を持たせてみよう。

Java

public enum SeasonWithTemp {
    SPRING(15),  // 春は平均15度
    SUMMER(28),  // 夏は平均28度
    AUTUMN(18),  // 秋は平均18度
    WINTER(5);   // 冬は平均5度

    private final int averageTemperature; // 平均気温を保持するフィールド

    // コンストラクタ
    SeasonWithTemp(int averageTemperature) {
        this.averageTemperature = averageTemperature;
    }

    // 平均気温を取得するメソッド
    public int getAverageTemperature() {
        return averageTemperature;
    }

    // 各季節のメッセージを返すメソッドも追加してみよう
    public String getSeasonMessage() {
        switch (this) { // thisは現在のEnum定数を指す
            case SPRING:
                return "出会いと別れの季節、春です。";
            case SUMMER:
                return "太陽がまぶしい夏!";
            case AUTUMN:
                return "食欲の秋!";
            case WINTER:
                return "こたつでみかんの季節です。";
            default:
                return "Unknown season.";
        }
    }
}

どう?ただの定数じゃなくて、それぞれの定数が自分自身の情報(平均気温)と振る舞い(メッセージを返す)を持ってるのがわかるかな?

これを実際に使ってみよう。

Java

public class EnumWithDetailsExample {
    public static void main(String[] args) {
        SeasonWithTemp summer = SeasonWithTemp.SUMMER;

        System.out.println("夏の平均気温: " + summer.getAverageTemperature() + "度");
        System.out.println(summer.getSeasonMessage());

        SeasonWithTemp winter = SeasonWithTemp.WINTER;
        System.out.println("冬の平均気温: " + winter.getAverageTemperature() + "度");
        System.out.println(winter.getSeasonMessage());

        // すべてのEnum定数をループすることもできる
        System.out.println("--- 全ての季節 ---");
        for (SeasonWithTemp season : SeasonWithTemp.values()) { // values()メソッドでEnumの定数全てを配列で取得できる
            System.out.println(season.name() + ": 平均気温 " + season.getAverageTemperature() + "度, メッセージ: " + season.getSeasonMessage());
        }
    }
}

実行結果:

夏の平均気温: 28度
太陽がまぶしい夏!
冬の平均気温: 5度
こたつでみかんの季節です。
--- 全ての季節 ---
SPRING: 平均気温 15度, メッセージ: 出会いと別れの季節、春です。
SUMMER: 平均気温 28度, メッセージ: 太陽がまぶしい夏!
AUTUMN: 平均気温 18度, メッセージ: 食欲の秋!
WINTER: 平均気温 5度, メッセージ: こたつでみかんの季節です。

こんな感じで、Enumをクラスのように扱うことで、より柔軟で表現豊かなコードが書けるようになるんだ。

vscodeで実行した結果

よく使うEnumのメソッド

Enumには、いくつか便利なメソッドが最初から用意されているんだ。

  • name(): Enum定数の名前(文字列)を取得する。
  • ordinal(): Enum定数が宣言された順序(0から始まるインデックス)を取得する。
  • valueOf(String name): 指定した名前のEnum定数を取得する。
  • values(): Enumのすべての定数を配列として取得する。

さっきの例でもname()values()を使ったね。これらはEnumを使う上で非常に役立つから覚えておくと良いよ。

定数定義とEnum、どう使い分ける?

前回の記事で学んだpublic static finalで定義する定数と、今回のEnum。結局どっちを使えばいいの?って思うよね。

簡単な目安としては、

  • 単一の、独立した定数: 例えば、消費税率(public static final double TAX_RATE = 0.10;)のように、それ単体で意味を持つ値ならfinalキーワードで定義する定数でOK。
  • 関連性のある定数の集合: 曜日、月、信号の色、ユーザーのステータスなど、いくつかの選択肢の中からひとつを選ぶようなケースでは、Enumを使うのが断然おすすめ!

Enumを使うことで、コードの可読性、保守性、そして何よりも「型安全」がぐっと向上するんだ。特に大規模なシステム開発では、Enumの活用は必須と言っても過言じゃないよ。


まとめ

今回はJavaの**列挙型(Enum)**について学んだね。

  • Enumは関連する定数をひとつのグループにまとめることができる特殊なクラス。
  • 型安全で、間違った値を設定するのを防いでくれる。
  • コードの可読性が向上し、switch文との相性が抜群。
  • フィールドやメソッドを持たせることで、より高機能な定数として使える。

Enumを使いこなせると、君のJavaプログラミングが一段とレベルアップするはず!ぜひ色々な場面で使ってみて、その便利さを実感してみてね。

コメント

タイトルとURLをコピーしました