JavaでNumberFormatExceptionになる空文字やカンマ、全角数字の対処を解説する記事のアイキャッチ。

実装・エラー解決

JavaでNumberFormatExceptionになる原因|空文字・カンマ・全角数字の対処

AIによる要約

NumberFormatExceptionは、文字列が対象の数値型として解釈できない場合に発生します。空文字、空白、3桁カンマ、全角数字、小数点、単位付き、int範囲外など原因は複数です。例外をcatchして0へ変換すると未入力や不正値を隠します。入力仕様を決め、文字列段階の形式チェック、必要な正規化、適切な数値型への変換、利用者向けエラーの返却を境界で行います。

新人SE
新人SE
画面では数字に見えるのに、Integer.parseIntでNumberFormatExceptionになりました。
ポンコツSE
ポンコツSE
空白、カンマ、全角、小数点などが含まれるとintとして解析できません。実際の文字列と仕様を確認します。

画面入力、CSV、環境変数、外部APIは、数値に見えるデータも最初は文字列です。Integer.parseIntへ渡すだけで変換できますが、入力形式が1文字でも違えばNumberFormatExceptionになります。

よくある修正はtry-catchして0を返すことですが、未入力、形式不正、値0を同じにしてしまいます。どの文字列を許可し、どのエラーとして返すかを入力境界で決めます。

この記事のポイント

  • 空文字や空白はparseIntできない
  • カンマ・全角数字・単位付きはそのまま変換できない
  • int範囲外でもNumberFormatExceptionになる
  • 不正値を0へ置き換えて隠さない
  • 画面・CSV・APIごとに入力契約とエラーを決める

NumberFormatExceptionが起きる基本例

Integer.parseIntは、符号付き10進整数として正しい文字列を受け取ります。空文字、空白だけ、小数、英字を含む値は変換できません。

Integer.parseInt("");       // 例外
Integer.parseInt(" ");      // 例外
Integer.parseInt("12.5");   // 例外
Integer.parseInt("12個");   // 例外
Integer.parseInt("123");    // 123

例外メッセージに入力値が表示されることがあります。本番ログへ個人情報や秘密値を出さないよう、記録方法にも注意します。

空文字と空白を先に扱う

任意入力なら、未入力をnullとして扱うのか既定値にするのかを決めてから変換します。必須入力なら、数値変換より前に必須エラーとして返す方が利用者へ伝わります。

Integer parseOptionalInt(String value) {
    if (value == null || value.isBlank()) {
        return null;
    }
    return Integer.valueOf(value.strip());
}

戻り値nullをServiceへ広げると別のNPEを生むことがあります。Formでは文字列、変換後DTOではIntegerなど、境界と内部型を分ける設計も検討します。

カンマ付き数値をどう扱うか

1,234はInteger.parseIntでは変換できません。カンマ入力を許可する仕様なら、単純にreplaceする前に形式が正しいか確認します。12,34まで1234として通すのは望ましくありません。

NumberFormat format = NumberFormat.getIntegerInstance(Locale.JAPAN);
format.setParseIntegerOnly(true);

Number number = format.parse("1,234");
System.out.println(number.intValue()); // 1234

NumberFormatは途中まで解析して残りを無視する場合があるため、ParsePositionで文字列全体を消費したか確認するなど厳密な検証が必要です。金額入力用の共通部品があればそれを使います。

全角数字とUnicode正規化

日本語入力では123が来ることがあります。全角を半角へ変換して受け付けるか、形式エラーにするかは画面仕様です。無条件にすべてNFKC正規化すると、記号や単位まで変わる可能性があります。

String normalized = Normalizer.normalize(
        input, Normalizer.Form.NFKC);
int value = Integer.parseInt(normalized);

正規化対象を数値入力欄に限定し、元の入力と変換後を混同しません。監査要件がある場合は原文を保持する必要もあります。

桁あふれでもNumberFormatException

文字がすべて数字でも、intの範囲を超えると変換できません。IDや金額が将来大きくなる場合、型選択を確認します。

Integer.parseInt("2147483647"); // 最大値
Integer.parseInt("2147483648"); // NumberFormatException

long id = Long.parseLong("2147483648");

longでも足りない整数、または桁数を失いたくないコード値ならBigIntegerやStringを検討します。電話番号、郵便番号、商品コードは計算しないため、数字だけでも数値型が適切とは限りません。

小数と金額は適切な型へ変換する

小数をIntegerへ変換するのではなく、用途に合う型を使います。金額や率ではBigDecimalを文字列から作ると、double経由の誤差を避けられます。

BigDecimal amount = new BigDecimal("1234.50");

// 避けたい例
BigDecimal inaccurate = new BigDecimal(0.1);

BigDecimalでもカンマや通貨記号はそのまま受け付けません。入力フォーマットの解析と、内部の数値表現を分けます。

例外を業務エラーへ変換する

低レベルのNumberFormatExceptionをそのまま500エラーにせず、入力境界で項目エラーへ変換します。すべてのExceptionをcatchせず、対象を限定します。

try {
    return Integer.valueOf(value);
} catch (NumberFormatException e) {
    throw new InvalidInputException(
            "quantity", "数量は整数で入力してください", e);
}

画面FormならBean Validationの@Patternや型変換エラー、REST APIなら400レスポンスのフィールドエラーへ統一します。スタックトレースを利用者へ返さないでください。

JUnitで不正パターンを並べる

正常値だけでなく、null、空、前後空白、カンマ、全角、小数、負数、最大値超過をパラメータ化します。許可する形式だけを明示します。

@ParameterizedTest
@ValueSource(strings = {"", " ", "1,000", "123", "1.5", "2147483648"})
void 不正な整数を拒否する(String input) {
    assertThrows(InvalidInputException.class,
            () -> parser.parseQuantity(input));
}

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

数値変換のレビューではcatchの有無ではなく、入力形式、正規化、型の範囲、不正時の利用者向けエラーが一貫しているかを見ます。

// レビューコメント例
NumberFormatExceptionをcatchして0にすると、不正入力と数量0を区別できません。
項目エラーとして返してください。

// レビューコメント例
カンマをreplaceするだけでは12,34も通ります。
許可する形式を定義し、文字列全体を検証してください。

// レビューコメント例
この値は商品コードで計算しません。先頭0も必要なので、
IntegerではなくStringのまま扱う方が契約に合います。

表示上数字に見えるかではなく、実際の文字列、許可形式、内部型を確認します。不正値を既定値へ落とす場合は、仕様として明記されていることが必要です。

提出前のセルフチェック

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

  • null・空文字・空白の扱いを決めたか
  • カンマや全角数字を許可するか
  • 正規化が他の文字を変えないか
  • 小数を整数型へ入れようとしていないか
  • intやlongの範囲を超えないか
  • コード値を数値型にする必要があるか
  • 不正値を0で隠していないか
  • 項目エラーとして利用者へ返せるか

Javaの型と例外を基本から確認する参考書

文字列、数値型、例外処理を一緒に整理すると、変換失敗をcatchで隠さず、入力境界で正しく扱えるようになります。

書籍「スッキリわかるJava入門 第5版」の表紙
商品画像:Amazon.co.jp
PR Java初学者向け

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

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

Java文法とオブジェクト指向を、最初から整理する一冊。

豊富な図とサンプルで、変数、条件分岐、クラス、例外処理まで順番に学べます。Javaの最初の教科書を探している人向けです。

  • Javaを基礎から体系的に学びたい
  • Java 25 LTS対応の入門書を選びたい

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

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

まとめ

NumberFormatExceptionは、空文字、空白、カンマ、全角、小数、単位付き、型の範囲外など、対象の数値型として解釈できない文字列で発生します。

例外をcatchして0へ置き換えず、許可形式、正規化、内部型、不正時のエラーを入力境界で決めます。正常値と不正パターンをテストし、コード値と計算値も区別してください。

-実装・エラー解決
-,