Enum の使い方(プロパティとメソッド) — 定数管理
「限られた選択肢」を型として安全に扱うのが enum。単なる定数集ではなく、プロパティやメソッドを持てる“小さなクラス”です。業務コードの「状態」「コード値」「表示名」を一箇所にまとめ、分岐をスッキリさせます。
基本構文と最小例
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
Java- 意味: Day は「この7つの値しか取り得ない」型になる。
- 参照:
Day today = Day.MONDAY; - 比較:
==で安全に比較できる(同一インスタンス保証)。
プロパティ(フィールド)を持たせる
public enum OrderStatus {
NEW("新規", 1),
PAID("支払済み", 2),
SHIPPED("出荷済み", 3),
CANCELED("キャンセル", 9);
private final String label; // 表示名
private final int code; // 外部連携用コード
OrderStatus(String label, int code) {
this.label = label;
this.code = code;
}
public String getLabel() { return label; }
public int getCode() { return code; }
}
Java- ポイント: enumのコンストラクタは常に private。各定数に引数を渡して初期化する。
- 用途: 表示名、コード値、重み、色、ロール権限などをひとまとめに。
メソッドを持たせる(ロジック・変換)
public enum Severity {
INFO(0), WARN(1), ERROR(2);
private final int level;
Severity(int level) { this.level = level; }
public int level() { return level; }
public boolean isSerious() { return level >= 1; }
public static Severity fromLevel(int level) {
for (Severity s : values()) {
if (s.level == level) return s;
}
throw new IllegalArgumentException("未知レベル: " + level);
}
}
Java- ポイント:
values()は全定数を返す。逆引きに便利。 - 変換メソッド: fromXxx を定義して、外部値→enum を集中管理。
switch と enum(分岐の定番)
public String actionMessage(OrderStatus s) {
return switch (s) {
case NEW -> "注文を受付ました";
case PAID -> "入金確認済み";
case SHIPPED -> "配送中です";
case CANCELED -> "キャンセルされました";
};
}
Java- ポイント: switch は全ケース網羅をチェックするので抜け漏れ防止になる。
例題で身につける
例題1: 月の表示と日数(うるう年対応)
public enum Month {
JAN(1, "1月"), FEB(2, "2月"), MAR(3, "3月"), APR(4, "4月"),
MAY(5, "5月"), JUN(6, "6月"), JUL(7, "7月"), AUG(8, "8月"),
SEP(9, "9月"), OCT(10, "10月"), NOV(11, "11月"), DEC(12, "12月");
private final int number;
private final String label;
Month(int number, String label) { this.number = number; this.label = label; }
public int number() { return number; }
public String label() { return label; }
public int days(boolean leapYear) {
return switch (this) {
case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;
case APR, JUN, SEP, NOV -> 30;
case FEB -> leapYear ? 29 : 28;
};
}
public static Month fromNumber(int n) {
for (Month m : values()) if (m.number == n) return m;
throw new IllegalArgumentException("1-12のみ: " + n);
}
}
Java- 狙い: 表示・番号・日数計算をひとつに集約。
例題2: ロールと権限チェック
public enum Role {
USER(Set.of("READ")),
ADMIN(Set.of("READ", "WRITE", "DELETE"));
private final Set<String> permissions;
Role(Set<String> permissions) { this.permissions = permissions; }
public boolean can(String permission) {
return permissions.contains(permission);
}
}
Java- 狙い: 文字列定数の散乱を防ぎ、権限を型で管理。
例題3: 支払いステータスの状態遷移
public enum PaymentStatus {
INIT {
@Override public PaymentStatus next(boolean ok) { return ok ? AUTHED : FAILED; }
},
AUTHED {
@Override public PaymentStatus next(boolean ok) { return ok ? CAPTURED : FAILED; }
},
CAPTURED { @Override public PaymentStatus next(boolean ok) { return this; } },
FAILED { @Override public PaymentStatus next(boolean ok) { return this; } };
public abstract PaymentStatus next(boolean ok);
}
Java- 狙い: 定数ごとに異なる振る舞いを持たせる(定数ごとのクラス本体)。
すぐ使えるテンプレート
- 属性つき定数
public enum X {
A("labelA", 100), B("labelB", 200);
private final String label; private final int code;
X(String label, int code) { this.label = label; this.code = code; }
public String label() { return label; }
public int code() { return code; }
}
Java- 逆引き(コード→enum)
public static X of(int code) {
for (X x : values()) if (x.code == code) return x;
throw new IllegalArgumentException("unknown: " + code);
}
Java- 定数ごとの振る舞い
public enum Op {
ADD { @Override public int apply(int a, int b) { return a + b; } },
MUL { @Override public int apply(int a, int b) { return a * b; } };
public abstract int apply(int a, int b);
}
Java実務のコツと落とし穴
- 明確な責務: 表示・コード・ロジックを enum に集約すると分岐が減る。
- 外部値取り込み: DBやAPIのコード値は enum のプロパティ+逆引きメソッドで統一。
- 名前付け: 定数は大文字+アンダースコア。プロパティやメソッドは通常の命名。
- JSON/DB連携: シリアライズは
name()かcodeを使うかを最初に決める。将来変更しやすいのはコード用フィールド。 - 過剰肥大化を避ける: 大量のロジックは別クラスへ。enumは「定数+小さな振る舞い」に留める。
まとめ
- enumは“型安全な定数集”+“小さなクラス”として使える。プロパティで意味を持たせ、メソッドで振る舞いを定義する。
- switch と逆引きメソッドで分岐と変換を統一し、保守性を高める。
- 定数ごとの振る舞いで「状態遷移」「演算」などもスッキリ書ける。
