核心一句话NumberFormatException 是在将非数字字符串转换为 intInteger 时抛出的运行时异常,主要发生在 Integer.parseInt()Integer.valueOf() 方法中,必须通过 try-catch 或预校验进行安全处理。


一、异常定义

  • 异常类java.lang.NumberFormatException
  • 继承自IllegalArgumentExceptionRuntimeException
  • 是否检查异常(运行时异常,编译器不强制要求捕获)
  • 何时抛出:当字符串无法解析为有效整数时

二、哪些方法会抛出 NumberFormatException

方法 说明
Integer.parseInt(String s) 将字符串转为 int 基本类型
Integer.valueOf(String s) 将字符串转为 Integer 对象(内部调用 parseInt
new Integer(String s) 已废弃,但也会抛出

✅ 所有基于字符串的整数解析操作都可能触发此异常。


三、常见触发场景(附示例)

❌ 场景 1:空字符串或 null

Integer.parseInt(null);     // ❌ 抛出 NPE(空指针)
Integer.parseInt("");       // ❌ NumberFormatException

❌ 场景 2:非数字字符

Integer.parseInt("abc");    // ❌
Integer.parseInt("12.34");  // ❌ 小数点不是整数
Integer.parseInt("12a");    // ❌ 混合字符
Integer.parseInt("  ");     // ❌ 空白字符

❌ 场景 3:超出 int 范围

Integer.parseInt("9999999999"); // ❌ 超出 int 最大值 2147483647
Integer.parseInt("-9999999999"); // ❌ 超出最小值 -2147483648

❌ 场景 4:带空格(无自动 trim)

Integer.parseInt(" 123 ");  // ❌ 抛异常(除非使用 trim)

四、异常处理方式(3种主流方案)

✅ 方案 1:try-catch 捕获异常(最常用)

public static int parseSafe(String str) {
    try {
        return Integer.parseInt(str);
    } catch (NumberFormatException e) {
        System.err.println("解析失败: " + str);
        return 0; // 或抛出自定义异常、返回 Optional 等
    }
}

// 使用
int num = parseSafe("abc"); // 返回 0,不崩溃

✅ 优点:灵活,可自定义默认值或错误处理逻辑
⚠️ 缺点:性能略低(异常开销大),不适用于高频解析


✅ 方案 2:预校验 + try-catch(推荐用于高频场景)

public static boolean isInteger(String str) {
    if (str == null || str.trim().isEmpty()) return false;
    str = str.trim();

    int startIndex = 0;
    if (str.charAt(0) == '-' || str.charAt(0) == '+') startIndex = 1;

    if (startIndex >= str.length()) return false; // 只有符号

    for (int i = startIndex; i < str.length(); i++) {
        if (!Character.isDigit(str.charAt(i))) {
            return false;
        }
    }

    // 可选:检查是否超出 int 范围(较复杂,可省略)
    try {
        Integer.parseInt(str);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

// 使用
String input = "123";
if (isInteger(input)) {
    int num = Integer.parseInt(input);
}

✅ 优点:避免频繁抛异常,性能更好
⚠️ 缺点:代码略复杂


✅ 方案 3:返回 Optional<Integer>(函数式编程风格)

public static Optional<Integer> tryParse(String str) {
    try {
        return Optional.of(Integer.parseInt(str));
    } catch (NumberFormatException e) {
        return Optional.empty();
    }
}

// 使用
Optional<Integer> result = tryParse("abc");
if (result.isPresent()) {
    int num = result.get();
} else {
    System.out.println("解析失败");
}

// 或使用 orElse
int num = tryParse("abc").orElse(0);

✅ 优点:语义清晰,避免 null,适合链式调用
⚠️ 缺点:Java 8+ 才支持


五、最佳实践 ✅

1. 永远不要假设输入是合法数字

// ❌ 危险
int num = Integer.parseInt(userInput);

// ✅ 安全
int num = tryParse(userInput).orElse(DEFAULT_VALUE);

2. 对用户输入、配置文件、网络数据做严格校验

String portStr = config.getProperty("port");
int port = tryParse(portStr).filter(p -> p > 0 && p < 65536)
                           .orElseThrow(() -> new ConfigException("端口无效"));

3. 避免在循环中频繁抛异常

// ❌ 高频抛异常,性能差
for (String s : strings) {
    try {
        int n = Integer.parseInt(s);
    } catch (NumberFormatException e) { }
}

// ✅ 先校验
for (String s : strings) {
    if (isInteger(s)) {
        int n = Integer.parseInt(s);
    }
}

4. 使用 Apache Commons 或 Guava(生产环境推荐)

使用 Apache Commons Lang

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

int num = NumberUtils.toInt("abc", 0); // 解析失败返回 0
boolean isNum = NumberUtils.isCreatable("123"); // 安全校验

使用 Google Guava

import com.google.common.primitives.Ints;

Integer num = Ints.tryParse("abc"); // 返回 null 而非抛异常

✅ 推荐在项目中引入这些库,避免重复造轮子。


六、自定义安全解析工具类(推荐)

public class SafeIntParser {

    public static int parseInt(String str, int defaultValue) {
        try {
            return Integer.parseInt(str.trim());
        } catch (NumberFormatException | NullPointerException e) {
            return defaultValue;
        }
    }

    public static Optional<Integer> tryParse(String str) {
        try {
            return Optional.of(Integer.parseInt(str.trim()));
        } catch (NumberFormatException | NullPointerException e) {
            return Optional.empty();
        }
    }

    public static boolean isValidInteger(String str) {
        if (str == null || (str = str.trim()).isEmpty()) return false;
        try {
            Integer.parseInt(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
}

七、常见错误 ❌

错误 正确做法
Integer.parseInt(null) 先判空
Integer.parseInt(" 123 ") trim()
== 比较解析结果 .equals()Objects.equals()
switch 中使用 Integer 先判空或转 int

八、总结:快速掌握要点 ✅

项目 内容
异常来源 parseInt, valueOf, new Integer(String)
常见原因 空、非数字、超出范围、格式错误
处理方式 try-catch、预校验、Optional、工具库
最佳实践 不信输入、预校验、用 Optional 或默认值
推荐工具 NumberUtils.toInt(), Ints.tryParse()
性能建议 避免在循环中频繁抛异常
安全建议 所有外部输入都需校验

🎯 一句话总结:

NumberFormatException 是字符串转整数时的“拦路虎”,必须通过 try-catch、预校验或使用 Optional/工具库进行安全处理,永远不要假设输入是合法数字,尤其是在处理用户输入、配置或网络数据时。