Enum名前一覧は「コード上の識別子を“文字列の一覧”として取り出す」技
Enum は「定数の集合」ですが、その一つ一つには「名前(識別子)」があります。Status.NEW の NEW の部分です。
業務では、この「Enum の名前だけ」を一覧で欲しい場面がよくあります。
ログに出したい、設定ファイルに書きたい、外部システムに「有効な値一覧」として渡したい、などです。
ここでは、「Enum の“名前一覧”を安全に取り出すユーティリティ」を、初心者向けにかみ砕いて整理します。
基本:Enum の名前は name() で取れる
まずはシンプルな Enum を用意します。
public enum Status {
NEW,
IN_PROGRESS,
DONE
}
Java各要素の「名前」は、name() メソッドで取得できます。
Status s = Status.NEW;
System.out.println(s.name()); // NEW
Javaここで大事なのは、name() が「Enum を宣言したときの識別子そのもの」を返す、という点です。
つまり、ソースコード上の NEW、IN_PROGRESS、DONE という文字列がそのまま返ってきます。
Enum名前一覧を List<String> で取得する
全要素の名前一覧を取りたいときは、values() と name() を組み合わせます。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public final class EnumNames {
private EnumNames() {}
public static List<String> namesOfStatus() {
return Arrays.stream(Status.values())
.map(Status::name)
.collect(Collectors.toList());
}
}
Java使い方はこうなります。
List<String> names = EnumNames.namesOfStatus();
System.out.println(names); // [NEW, IN_PROGRESS, DONE]
Javaここでの重要ポイントは三つあります。
一つ目は、「Status.values() で全要素を配列として取り出し、それを Arrays.stream で Stream に変換している」ことです。
これで「Enum の全要素を順番に処理する流れ」が作れます。
二つ目は、「map(Status::name) で“Enum → その名前(String)”に変換している」ことです。Status 型の Stream が、String 型の Stream に変わります。
三つ目は、「collect(Collectors.toList()) で List<String> にまとめている」ことです。
これで「Enum の名前一覧」が、普通の文字列リストとして扱えるようになります。
汎用ユーティリティにして、どの Enum でも使えるようにする
Status 専用ではなく、「どの Enum にも使える」形にすると、再利用性がぐっと上がります。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public final class EnumNames {
private EnumNames() {}
public static <E extends Enum<E>> List<String> namesOf(Class<E> enumType) {
return Arrays.stream(enumType.getEnumConstants())
.map(Enum::name)
.collect(Collectors.toList());
}
}
Java使い方の例です。
List<String> statusNames = EnumNames.namesOf(Status.class);
// [NEW, IN_PROGRESS, DONE]
List<String> threadStateNames = EnumNames.namesOf(Thread.State.class);
// [NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED]
Javaここでの重要ポイントは二つです。
一つ目は、「Class<E>#getEnumConstants() で、その Enum 型の全定数を配列として取得している」ことです。Status.values() と同じ情報ですが、型を引数で受け取れるので汎用化できます。
二つ目は、「map(Enum::name) と書くことで、“どの Enum 型でも name() を呼ぶ”共通処理にしている」ことです。E が何であっても、Enum である限り name() が呼べます。
名前一覧をどこで使うか:具体的な業務イメージ
例えば、外部設定ファイルに「有効なステータス名だけ書いてよい」という仕様があるとします。
そのとき、「有効な値一覧」をログやエラーメッセージに出したくなります。
String allowed = String.join(", ", EnumNames.namesOf(Status.class));
System.out.println("status は次のいずれかで指定してください: " + allowed);
// status は次のいずれかで指定してください: NEW, IN_PROGRESS, DONE
Javaまた、API で「この項目に指定できる値一覧」を返すエンドポイントを作ることもあります。
record EnumOption(String name) {}
List<EnumOption> options =
EnumNames.namesOf(Status.class).stream()
.map(EnumOption::new)
.toList();
Java「Enum の名前一覧」が取れるだけで、こうした「有効値の公開」が簡単になります。
name() と code/label をどう使い分けるか
業務では、Enum に「code」「label」を持たせることが多いです。
そのとき、「name() を外部に出すかどうか」は設計のポイントになります。
name() は「ソースコード上の識別子」なので、
外部仕様として固定してしまうと、「名前を変えたい」ときに互換性問題が起きます。
一方で、「ログやデバッグ用」「内部向けのメッセージ」なら、name() をそのまま使うのは十分アリです。
つまり、
外部インターフェース(API、DB、設定ファイル)には code を使う
内部ログや開発者向けメッセージには name() を使う
という使い分けを意識すると、後々楽になります。
Enum名前一覧ユーティリティは、「内部向けに“今定義されている名前を全部知りたい”」ときに特に役立ちます。
まとめ:Enum名前一覧ユーティリティで身につけてほしい感覚
Enum名前一覧は、
単に「values() と name() を知る」話ではなく、
「Enum を“選択肢の定義”として扱い、その識別子一覧を安全に取り出す技」です。
Status.values() から map(Status::name) で名前一覧を作る、という基本パターンを押さえる。
汎用メソッド namesOf(Class<E>) を用意して、どの Enum でも同じ書き方で名前一覧を取れるようにする。
name() は「内部向けの識別子」として使い、外部仕様には code など別の値を使う、という設計を意識する。
あなたのコードのどこかに、
Enum の名前を手書きで列挙している箇所があれば、
それを一度「Enum名前一覧ユーティリティ」に置き換えられないか眺めてみてください。
その小さな整理が、
「Enum を“生きた選択肢定義”として、気持ちよく扱えるエンジニア」への、
確かな一歩になります。
