JavaのNo enum constantエラー原因とEnum.valueOfの安全な使い方を解説する記事のアイキャッチ。

広告 Java

Javaの「No enum constant」エラー原因|Enum.valueOfの安全な使い方

AIによる要約

Enum.valueOfは、受け取った文字列を列挙定数名と大文字小文字まで含めて完全一致で探します。ACTIVEが定義されていてもactiveや末尾空白付きのACTIVEは一致せず、IllegalArgumentExceptionとNo enum constantが発生します。nullはNullPointerExceptionです。外部入力を無条件にvalueOfへ渡したり、すべて大文字へ直したりせず、APIや画面で受け付ける値を決め、必要なら業務用コードを持つfromValueメソッドで変換します。

この記事は2026年8月29日分のX向けJavaクイズを詳しく解説したものです。問題と回答は本文内でも確認できます。

新人SE
新人SE
画面からactiveが送られたら、ACTIVEのEnumへ自動で変換されると思っていました。
ポンコツSE
ポンコツSE
Enum.valueOfは大文字小文字まで完全一致です。activeとACTIVEは別の文字列として扱われます。

ステータス、権限、種別、処理区分など、決められた値だけを扱うためにEnumを使います。文字列からEnumへ変換するときに便利なのがvalueOfですが、入力値が列挙定数名と一致しないと例外になります。

スタックトレースにNo enum constantと出ていたら、まずEnumの定義と実際に渡された文字列を並べてください。見た目が近くても、大文字小文字、空白、ハイフン、全角文字が異なれば一致しません。

この記事のポイント

  • Enum.valueOfは列挙定数名と完全一致が必要
  • 大文字小文字と前後空白も区別される
  • 不一致はIllegalArgumentExceptionになる
  • nullはNullPointerExceptionになる
  • 外部値には業務用の変換ルールを用意する
  • SpringではController到達前に400になる場合がある

まずはXのJavaクイズを確認する

ACTIVEとINACTIVEを持つStatus列挙型へStatus.valueOfのactiveを渡した結果を問うJavaクイズ画像。
小文字のactiveは、ACTIVEへ変換されるのでしょうか。
enum Status {
    ACTIVE,
    INACTIVE
}

Status status = Status.valueOf("active");
System.out.println(status);

答えはCのIllegalArgumentExceptionです。例外メッセージにはNo enum constant ...Status.activeと表示されます。

答えはIllegalArgumentExceptionで、Enum.valueOfは列挙定数名と大文字小文字まで完全一致が必要と説明する画像。
activeとACTIVEは別です。valueOfは自動で大文字へ変換しません。

No enum constantエラーが出る条件

Enum.valueOfは、指定されたEnum型に、引数と同じ名前の列挙定数があるか検索します。名前は完全一致です。

Status.valueOf("ACTIVE");   // ACTIVE
Status.valueOf("active");   // IllegalArgumentException
Status.valueOf("ACTIVE ");  // IllegalArgumentException
Status.valueOf("");         // IllegalArgumentException
Status.valueOf(null);       // NullPointerException

大文字小文字だけでなく、末尾の空白も一致しません。nullだけは「名前が見つからない」のではなく、引数自体がないためNullPointerExceptionです。catchする例外を1種類に決めつけないでください。

列挙定数名は外部仕様とは限らない

Javaコード内ではACTIVEという定数名でも、画面やAPIではactive、DBでは1、CSVでは有効を使うことがあります。外部値とJavaの識別子を同じにする必然性はありません。

外部仕様をvalueOfへ直接結び付けると、Enum定数の改名がAPIや保存データの互換性に影響します。内部名と外部コードを分けるかは、システムの寿命と連携先を考えて決めます。

toUpperCaseで直す場合の注意

入力仕様として大文字小文字を区別しないなら、正規化してからvalueOfする方法があります。ロケールに依存しない識別子変換ではLocale.ROOTを指定します。

Status parseStatus(String input) {
    if (input == null || input.isBlank()) {
        throw new IllegalArgumentException("status is required");
    }

    return Status.valueOf(
            input.trim().toUpperCase(Locale.ROOT));
}

ただし、無条件にtrimと大文字化をすると、本来エラーにすべき表記まで受け付けます。連携APIがactiveだけを正式値とするなら、ACTIVEも許可してよいかは別問題です。正規化は仕様として実装します。

外部値用のfromValueを用意する

外部へ公開する値が列挙定数名と異なるなら、Enum自身にコードを持たせ、変換処理を1か所へまとめます。

enum Status {
    ACTIVE("active"),
    INACTIVE("inactive");

    private final String value;

    Status(String value) {
        this.value = value;
    }

    static Optional<Status> fromValue(String input) {
        if (input == null) {
            return Optional.empty();
        }

        return Arrays.stream(values())
                .filter(status -> status.value.equals(input))
                .findFirst();
    }
}

呼び出し側は、見つからなかった場合に入力エラーとして扱うのか、デフォルト値へ置き換えるのかを決めます。状態値で安易にデフォルトへ落とすと、不正データを正常として処理する危険があります。

Status status = Status.fromValue(input)
        .orElseThrow(() -> new IllegalArgumentException(
                "未対応のstatusです: " + input));

nullを返す変換メソッドは避ける

見つからなければnullを返す実装は、呼び出し側でnullチェックを忘れると、後続のswitchやメソッド呼び出しで別のNullPointerExceptionになります。元の入力エラーから離れた場所で落ちるため、調査が難しくなります。

Optionalで未変換を表す、入力境界で業務例外へ変える、Validationエラーへまとめるなど、プロジェクトの方針に合わせて失敗を明示します。

Spring BootではController前に400になる場合がある

Spring MVCのController引数へEnumを直接指定すると、リクエスト文字列からの変換に失敗した時点で400 Bad Requestになることがあります。Controllerメソッドの先頭にログを置いても出ない場合、引数変換を確認します。

@GetMapping("/orders")
String list(@RequestParam Status status) {
    // ?status=ACTIVE なら到達
    // ?status=active は変換時に400になる場合がある
    return service.find(status);
}

小文字を正式入力にするなら、文字列として受けて明示変換する、SpringのConverterを用意する、JSONならデシリアライズ方針を設定するなどの方法があります。Controllerごとに別の変換を増やさず、入力仕様を統一してください。

DB保存値とEnum名の変更に注意する

JPAでEnum名を文字列保存している場合、定数名の変更が既存データの読み込みへ影響します。画面表示名だけを変えたいのに定数名まで変更すると、過去データがNo enum constantになる可能性があります。

保存形式、移行SQL、旧値との互換期間を確認します。EnumのリファクタリングはJavaコード内だけで完結しない場合があります。

JUnitで正常値と不正値を確認する

@ParameterizedTest
@CsvSource({
    "active, ACTIVE",
    "inactive, INACTIVE"
})
void 外部値からStatusへ変換する(
        String input, Status expected) {
    assertEquals(expected,
            Status.fromValue(input).orElseThrow());
}

@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = {"unknown", "ACTIVE", " active "})
void 未対応値は変換しない(String input) {
    assertTrue(Status.fromValue(input).isEmpty());
}

この例は小文字だけを正式値にする契約です。大文字や前後空白も許可する仕様なら期待値を変えます。テストが変換仕様の文書になるよう、許可する入力を明示します。

現場レビューでよくある指摘

// レビューコメント例
Enum.valueOfは大文字小文字まで完全一致です。
画面から送られる値はactiveなので、このままでは例外になります。

// レビューコメント例
toUpperCaseで全表記を受け付けていますが、
API仕様として大文字小文字を区別しない認識でよいでしょうか。

// レビューコメント例
変換失敗時にnullを返すため、後続のswitchでNPEになります。
入力境界でエラーへ変換してください。

// レビューコメント例
Enum定数名の変更はDBの既存値へ影響します。
移行方法と旧値の扱いを確認してください。

提出前のセルフチェック

レビュー前に確認すること

  • 入力値とEnum定数名を実データで比較したか
  • 大文字小文字を区別する仕様か
  • 前後空白を許可する仕様か
  • nullと空文字の扱いを決めたか
  • valueOfの例外をそのまま利用者へ見せていないか
  • 外部コード用のfromValueが必要か
  • 変換失敗時にnullを返していないか
  • Springの引数変換で400にならないか
  • DB保存値とEnum名変更の影響を確認したか

JavaのEnumと例外を学ぶ参考書

Enumは定数の書き方だけでなく、フィールド、メソッド、switch、例外処理と組み合わせて使います。基本APIを体系的に確認すると、外部入力と内部型の境界を設計しやすくなります。

書籍「スッキリわかるJava入門 実践編 第5版」の表紙
商品画像:Amazon.co.jp
PR Java基礎学習後の若手向け

スッキリわかるJava入門 実践編 第5版

中山 清喬 (著), 株式会社フレアリンク (監修)

基礎文法の次に必要な、現場寄りのJava知識を補う。

コレクション、ジェネリクス、ラムダ式、ストリームなど、業務コードで出会いやすい機能を入門編の次に学べます。

  • Java基礎の次に何を学ぶか迷っている
  • コレクションやStreamを整理したい

当サイトはAmazonアソシエイト・プログラムの参加者です。価格・在庫・配送条件はAmazonでご確認ください。

この記事とあわせて読みたい

まとめ

No enum constantは、Enum.valueOfへ渡した文字列と一致する列挙定数名がないときに発生します。valueOfは大文字小文字、空白を含めて完全一致であり、nullはNullPointerExceptionです。

外部入力を直接valueOfへ渡さず、受け付ける値と正規化ルールを決めてください。必要なら外部コードを持つfromValueを用意し、変換失敗を入力境界で明示的なエラーへ変えます。Springの400やDB保存値への影響も合わせて確認します。

-Java
-, , ,