← Debugging Guides

阅读中文版本

Java NumberFormatException — Unparseable Numeric String

Fix NumberFormatException by trimming input, matching the radix to Integer.parseInt, and using the correct parse method for decimals and large numbers.

beginnerdebuggingjavaexceptionsparsing

Symptoms

  • java.lang.NumberFormatException: For input string: "12a"
  • Parsing works for small numbers but fails on large or decimal values
  • A form value with spaces cannot be converted

Possible causes

  • The string contains non-digit characters or surrounding whitespace
  • A decimal or scientific notation is parsed with parseInt instead of parseDouble
  • A value exceeds the range of int and needs long or BigInteger

Diagnosis steps

Reproduce and read the offending string

jshell -q <<'EOF'
try { Integer.parseInt(" 12 "); } catch (NumberFormatException e) { System.out.println(e.getMessage()); }
EOF

Interpretation

The message includes the exact string, exposing whitespace or stray characters.

Choose the right parse method

Double.parseDouble("3.14"); Long.parseLong("9000000000");

Interpretation

parseDouble handles decimals, parseLong handles values beyond int range.

Root cause

The parse methods accept only an optional sign and digits for the requested radix, with no leading or trailing whitespace. Anything else, including a decimal point for parseInt, throws NumberFormatException.

Fix

Trim and validate input, use Integer.parseInt with the correct radix, Double.parseDouble for decimals, Long.parseLong/BigInteger for large values, and NumberFormat for locale-formatted input.

Risk note

Locale-formatted numbers with commas need NumberFormat; parseInt rejects them even after trim.

Verify the fix

Rerun with the original input and confirm a correct value or a controlled validation error; add tests for whitespace, decimals, and overflow.

Symptoms

This debugging guide addresses “Java NumberFormatException — Unparseable Numeric String”. Start from the symptoms, follow the ordered diagnostics, and confirm each hypothesis before moving on; the fix and verification steps then close the loop.

Observed symptoms include:

  • java.lang.NumberFormatException: For input string: “12a”
  • Parsing works for small numbers but fails on large or decimal values
  • A form value with spaces cannot be converted

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Reproduce and read the offending string

jshell -q <<'EOF'
try { Integer.parseInt(" 12 "); } catch (NumberFormatException e) { System.out.println(e.getMessage()); }
EOF

The message includes the exact string, exposing whitespace or stray characters.

Step 2: Choose the right parse method

Double.parseDouble("3.14"); Long.parseLong("9000000000");

parseDouble handles decimals, parseLong handles values beyond int range.

Likely contributors, in order of frequency:

  • The string contains non-digit characters or surrounding whitespace
  • A decimal or scientific notation is parsed with parseInt instead of parseDouble
  • A value exceeds the range of int and needs long or BigInteger

Root Cause

The parse methods accept only an optional sign and digits for the requested radix, with no leading or trailing whitespace. Anything else, including a decimal point for parseInt, throws NumberFormatException.

The Fix

Trim and validate input, use Integer.parseInt with the correct radix, Double.parseDouble for decimals, Long.parseLong/BigInteger for large values, and NumberFormat for locale-formatted input.

Watch out: Locale-formatted numbers with commas need NumberFormat; parseInt rejects them even after trim.

public static int safeInt(String raw) {
    if (raw == null) throw new IllegalArgumentException("null input");
    String s = raw.trim();
    if (!s.matches("[+-]?\\d+")) {
        throw new IllegalArgumentException("not an integer: " + raw);
    }
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {
        return Math.toIntExact(Long.parseLong(s)); // precise overflow error
    }
}

Verify and Prevent

Rerun with the original input and confirm a correct value or a controlled validation error; add tests for whitespace, decimals, and overflow.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.