Java | Java 標準ライブラリ:NumberFormatException

Java Java
スポンサーリンク

NumberFormatException は「数字に変換できなかったときの例外」

NumberFormatException は、ざっくり言うと

「文字列を数字に変換しようとしたけど、数字としておかしいので無理です」

と Java が教えてくれる例外です。

代表的には、次のようなときに発生します。

Integer.parseInt("123");   // OK
Integer.parseInt("abc");   // NumberFormatException
Integer.parseInt("12a3");  // NumberFormatException
Java

parseIntparseLong など、「文字列 → 数値」に変換するメソッドは、
「これは数字として解釈できない」と判断した瞬間に NumberFormatException を投げます。


どんなときに起きるのかを具体例でつかむ

純粋に「数字じゃない」ケース

一番わかりやすいのは、数字以外の文字が混ざっているケースです。

public class Example1 {
    public static void main(String[] args) {
        String s1 = "123";
        String s2 = "abc";
        String s3 = "12a3";

        System.out.println(Integer.parseInt(s1));  // 123

        System.out.println(Integer.parseInt(s2));  // ここで NumberFormatException
        System.out.println(Integer.parseInt(s3));  // ここも NumberFormatException
    }
}
Java

"123" は問題なく int に変換できます。
しかし "abc""12a3" は、どう見ても「整数としておかしい」ので、
Java は「変換できません」と言って NumberFormatException を投げます。

空文字や null の扱い

空文字 "" も、数字としては不正です。

Integer.parseInt("");   // NumberFormatException
Java

一方で、null を渡すときは NumberFormatException ではなく NullPointerException です。

String s = null;
Integer.parseInt(s);    // NullPointerException
Java

つまり、

「文字列はあるけど、中身が数字として不正」 → NumberFormatException
「そもそも文字列が存在しない(null)」 → NullPointerException

という違いがあります。


よくある落とし穴パターン

空白や全角文字が混ざっているケース

一見数字っぽく見えているのに、例外になるパターンもあります。

String s1 = " 123";         // 先頭に半角スペース
String s2 = "123 ";         // 末尾に半角スペース
String s3 = "123";       // 全角数字
String s4 = "123\n";        // 改行付き

Integer.parseInt(s1);  // NumberFormatException
Integer.parseInt(s2);  // NumberFormatException
Integer.parseInt(s3);  // NumberFormatException
Integer.parseInt(s4);  // NumberFormatException
Java

parseInt はかなりシンプルに「0〜9 の半角数字と符号(+/-)」だけを見ています。
余計な空白や全角数字は、そのまま「不正な文字」として扱われます。

入力がユーザーや外部ファイルから来る場合は、

trim() で前後の空白を削る
「全角を半角に変換する」など前処理を行う

などをしてから parseInt するほうが安全です。

範囲外の数値

int の範囲外の数値も NumberFormatException になります。

// int の最大値は 2147483647
String s = "2147483648";    // 1 大きい

Integer.parseInt(s);        // NumberFormatException
Java

「文字としては数字だけど、その型の範囲を超えている」ときも
「その数としては不正」と見なされる、というイメージです。


NumberFormatException を「どう扱うか」が重要

そのままだとプログラムが落ちる

NumberFormatException は unchecked(実行時)例外なので、
try-catch しないで放っておくと、その場でスローされて処理が落ちます。

public static void main(String[] args) {
    String input = "abc";
    int value = Integer.parseInt(input);  // ここで例外 → 以降は実行されない
    System.out.println("value = " + value);
}
Java

これだと、ユーザーが「数字でないもの」を入力した瞬間にアプリが落ちてしまいます。
現実のアプリでは、それでは困るので、

「数字じゃなかったときにどうするか?」

を必ず考える必要があります。

try-catch で丁寧に扱う

一つの典型パターンは、try-catch で囲んでメッセージを出すことです。

public static void main(String[] args) {
    String input = "abc";

    try {
        int value = Integer.parseInt(input);
        System.out.println("入力された数値: " + value);
    } catch (NumberFormatException e) {
        System.out.println("数値として正しくありません: " + input);
    }
}
Java

こう書くことで、

数値として正しい → その値を使う
数値として不正 → エラーメッセージを出して、アプリは落とさない

という振る舞いにできます。

「数字だったら使う/ダメなら別の処理」という分岐

例えば、「入力が数字なら数値として扱い、違うなら 0 にする」というような処理も書けます。

public static int parseOrDefault(String s, int defaultValue) {
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {
        return defaultValue;
    }
}

public static void main(String[] args) {
    System.out.println(parseOrDefault("123", 0));  // 123
    System.out.println(parseOrDefault("abc", 0));  // 0
}
Java

このように、「ミス入力や不正データが来るかもしれない」前提で、
NumberFormatException をどう扱うかルールを決めておくのが大事です。


どうやって「NumberFormatException を減らすか」

変換前に「数字だけか」をチェックする

例外処理は必須ですが、「そもそも例外を出さない工夫」もできます。

例えば、「全部数字かどうか」を事前チェックする方法です。

public static boolean isInteger(String s) {
    if (s == null || s.isEmpty()) {
        return false;
    }
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (i == 0 && (c == '+' || c == '-')) {
            continue;  // 先頭の + / - は許可
        }
        if (!Character.isDigit(c)) {
            return false;
        }
    }
    return true;
}

public static void main(String[] args) {
    String s = "123";
    if (isInteger(s)) {
        int value = Integer.parseInt(s);
        System.out.println(value);
    } else {
        System.out.println("整数ではない入力: " + s);
    }
}
Java

こうすると、「数字かどうか」の判定を自分でコントロールできます。
ただし、ロジックが複雑になるので、
「本当に事前チェックが必要か? try-catch で足りないか?」は使い分けです。

入力 UI 側で制限をかけるという発想

実務では、「Java コードで何でも受けて例外で頑張る」のではなく、

フォーム側で数字しか入力できないようにする
バリデーションライブラリを使って形式チェックする

といったアプローチで、「不正な文字列が Java コードまで届かないようにする」ことも多いです。

それでも最終的には「それでもおかしなものが来るかも」と思って
NumberFormatException への備えをしておくのが堅実です。


まとめ:初心者として NumberFormatException をどう捉えるか

頭の中にこう整理しておくと扱いやすくなります。

文字列 → 数値への変換(Integer.parseInt など)で、
「その文字列を数字として解釈できない」ときに投げられる例外が NumberFormatException

起きる典型パターンは、数字以外の文字が混ざっている/空文字/範囲外など。
ユーザー入力や外部ファイルからのデータは、ほぼ確実にこのリスクがある。
だから、parseInt などを呼ぶところは、基本的に try-catch か事前チェックを入れる前提で設計する。

タイトルとURLをコピーしました