java.lang.NumberFormatException: For input string を Java で修正する方法

beginner Java2026-03-21| Java 8以降、任意のOS(Windows / Linux / macOS)、Integer.parseInt()、Long.parseLong()、Double.parseDouble() を使用する任意のフレームワーク

Error Message

java.lang.NumberFormatException: For input string: "abc"
#java#numberformat#パース#integer#文字列変換

TL;DRInteger.parseInt()(またはそれに類するメソッド)を、有効な数値でない文字列に対して呼び出しています。空文字列、単語、"1,000"のような値、余分なスペースも含め、すべてこのエラーを引き起こします。try-catchで囲むか、事前にバリデーションを行いましょう。

// 簡単な修正 — try-catchで囲む
try {
    int value = Integer.parseInt(input);
} catch (NumberFormatException e) {
    System.err.println("Invalid number: " + input);
    // デフォルト値の処理、エラーの返却など
}

このエラーが発生する原因スタックトレースの全体は次のようになります:

Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
    at java.base/java.lang.Integer.parseInt(Integer.java:668)
    at java.base/java.lang.Integer.parseInt(Integer.java:786)
    at com.example.Main.main(Main.java:8)

Javaのパースメソッドは厳格です。数字のみを受け付け、先頭に-または+を任意で付けられます。それだけです。それ以外はすべてNumberFormatExceptionをスローします。最もよくある原因:

  • バリデーションされていないユーザー入力("abc"""null)- 桁区切り文字付きの数値:"1,000"- 単位が付いた数値:"42px""5MB"- parseIntに渡された浮動小数点数文字列:"3.14"- 先頭または末尾に空白がある文字列:" 7 "- CSVやJSON、またはデータベースのカラムから読み取った値がnullまたは不正な形式だった場合## 修正方法### 1. try-catch(最も一般的)これが基本的な解決策です。不正な値と値なしを区別する必要がある場合や、問題を起こした文字列をログに記録したい場合に使用します。
public static Integer safeParseInt(String s) {
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {
        return null; // またはデフォルト値(0など)
    }
}

// 使用例
Integer age = safeParseInt(request.getParameter("age"));
if (age == null) {
    throw new IllegalArgumentException("age must be a number");
}

2. パース前に空白を除去する余分なスペースはこのエラーの最も気づきにくい原因の一つです。特にファイルやフォームフィールドから読み取った値に多く見られます。.trim()を一度呼び出すだけで解決することが多いです。

int value = Integer.parseInt(input.trim());

3. 事前に正規表現でバリデーションする不正な入力を最初の段階で拒否します。このアプローチにより、スタックトレースに埋もれた不可解な例外ではなく、明確で早期のエラーメッセージが得られます。

if (!input.matches("-?\\d+")) {
    throw new IllegalArgumentException("Expected an integer, got: " + input);
}
int value = Integer.parseInt(input);

4. ロケール形式の数値を処理する(1,000 / 1.000)parseIntはロケールの概念を持っていません。"1,234,567"は常に失敗します。特定の地域向けにフォーマットされた数値を読み取る際はNumberFormatに切り替えましょう。

import java.text.NumberFormat;
import java.util.Locale;

String formatted = "1,234,567";
NumberFormat nf = NumberFormat.getInstance(Locale.US);
long value = nf.parse(formatted).longValue(); // 1234567

5. 整数に見せかけた小数をパースする"3.14"を受け取ったが普通のintが必要な場合は、まずdoubleとしてパースしてからキャストします。結果は3になります。小数部分は切り捨てられ、四捨五入はされません。

String s = "3.14";
int value = (int) Double.parseDouble(s); // 3

6. Apache Commons Lang(オプションのユーティリティ)Commons Langをすでに使用していますか?NumberUtilsはnull、空文字列、不正な入力をスローせずに処理します。try-catchの定型コードは不要です。

import org.apache.commons.lang3.math.NumberUtils;

int value = NumberUtils.toInt("abc", 0);   // 0を返す(デフォルト値)
boolean valid = NumberUtils.isCreatable("123"); // true

7. Java 8+ Optionalパターン関数型パイプラインが好みですか?スローしたりnullを返したりする代わりにOptionalIntを返しましょう。値が存在しないことが明示的になり、コードに潜むサイレントなデフォルト値がなくなります。

import java.util.OptionalInt;

public static OptionalInt tryParseInt(String s) {
    if (s == null || s.isBlank()) return OptionalInt.empty();
    try {
        return OptionalInt.of(Integer.parseInt(s.trim()));
    } catch (NumberFormatException e) {
        return OptionalInt.empty();
    }
}

// 使用例
tryParseInt(input).ifPresentOrElse(
    val -> System.out.println("Parsed: " + val),
    ()  -> System.out.println("Not a valid integer")
);

注意すべきエッジケース- null入力Integer.parseInt(null)はNPEではなくNumberFormatExceptionをスローします。意外ですが、これが事実です。パースを呼び出す前に必ずnullチェックを行いましょう。- 整数オーバーフロー"99999999999"Integer.MAX_VALUE(2,147,483,647)を超えるためスローされます。大きな値にはLong.parseLong()またはnew BigInteger(s)を使用してください。- 16進数文字列"0xFF"は普通のparseIntでは失敗します。Integer.parseInt(s.substring(2), 16)またはよりシンプルなInteger.decode("0xFF")を使用してください。- 指数表記"1e5"は有効な整数文字列ではありません。まずDoubleとしてパースしてからキャストしてください。## 修正の確認パースユーティリティに対してこれらのアサーションを実行してください。厄介なエッジケースがすべてカバーされています。すべての行が通れば、リリース可能です。

// 基本的な有効入力
assert safeParseInt("42")   != null;
assert safeParseInt("-7")   != null;
assert safeParseInt(" 10 ") != null; // trimの後

// null / デフォルト値を返すべき — スローしてはいけない
assert safeParseInt("")     == null;
assert safeParseInt("abc")  == null;
assert safeParseInt(null)   == null;
assert safeParseInt("3.14") == null;
assert safeParseInt("1,000") == null; // カンマを先に除去しない限り

System.out.println("All checks passed");

例外が発生せず、出力にAll checks passedと表示されますか?修正は完了です。

クイックリファレンス- 空白の問題には.trim()を使用する- 信頼できないユーザー入力や外部データにはtry-catchを使用する- "1,000"のようなロケール形式の文字列にはNumberFormatを使用する- 小数文字列にはDouble.parseDouble()でパース後にキャストする- 2,147,483,647を超える値にはLong.parseLong()またはBigIntegerを使用する

Related Error Notes