← 中文资源

简体中文版本

Java NumberFormatException — 无法解析的数值字符串

通过去除输入空白、让进制匹配 Integer.parseInt,并对小数与大数选用正确的解析方法,修复 NumberFormatException。

阅读英文原文

症状

本篇指南处理“Java NumberFormatException — 无法解析的数值字符串”。请从症状出发,按顺序执行诊断,在推进前确认每个假设;随后通过修复与验证步骤闭环。

可观察到的症状包括:

  • java.lang.NumberFormatException: For input string: “12a”
  • 小数可解析,大数或小数失败
  • 带空格的表单值无法转换

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

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

消息包含确切字符串,暴露空白或杂散字符。

步骤 2

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

parseDouble 处理小数,parseLong 处理超出 int 范围的值。

常见诱因(按出现频率排序):

  • 字符串含非数字字符或首尾空白
  • 用 parseInt 解析了小数或科学计数法
  • 数值超出 int 范围,需用 long 或 BigInteger

根因

解析方法只接受可选符号与指定进制的数字,且不容忍首尾空白。其他输入(对 parseInt 而言包含小数点)都会抛 NumberFormatException。

修复

去除并校验输入,用正确的进制调用 Integer.parseInt,小数用 Double.parseDouble,大数用 Long.parseLong/BigInteger,本地化格式用 NumberFormat。

注意:含千位分隔符的本地化数字需用 NumberFormat;即便去掉空白,parseInt 仍会拒绝。

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
    }
}

验证

用原始输入重跑,确认得到正确值或受控校验错误;为空白、小数与溢出补充测试。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。