Java 常见异常系列:NumberFormatException 数字格式异常


网罗开发 (小红书、快手、视频号同名)

大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员

👋 大家好,我是展菲!

📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。

📣 公众号"Swift社区",每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。

💬 微信端添加好友"fzhanfei",与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。

📅 最新动态:2025 年 3 月 17 日

快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!

文章目录

    • 摘要
    • 引言
    • 问题示例
    • [为什么会出现 NumberFormatException?](#为什么会出现 NumberFormatException?)
    • 解决方案
      • [1. 输入校验](#1. 输入校验)
      • [2. 使用异常捕获](#2. 使用异常捕获)
      • [3. 选择合适的数据类型](#3. 选择合适的数据类型)
    • 实际场景
    • 总结

摘要

在开发中,NumberFormatException 是一个非常常见的异常。它通常出现在我们把字符串转成数字时,比如 Integer.parseInt()Double.valueOf() 等方法,输入的字符串不符合数字格式,就会抛出这个异常。

本文通过实际 Demo 展示异常产生的过程,并结合常见业务场景(比如读取配置、解析用户输入)来分析如何避免和解决。

引言

Java 中的基本包装类,比如 IntegerLongDouble 等,都提供了从字符串转数字的方法。但这些方法都有个前提:输入必须是一个合法的数字字符串

例如 "123" 可以成功转为 123,但是 "abc""12a"、甚至 "123.45"Integer 都会报错。

这种时候,就会抛出我们今天要讲的主角:

bash 复制代码
java.lang.NumberFormatException: For input string: "abc"

问题示例

Demo 代码

java 复制代码
public class NumberFormatDemo {
    public static void main(String[] args) {
        String valid = "123";
        String invalid = "abc";
        String decimal = "123.45";

        try {
            int num1 = Integer.parseInt(valid);
            System.out.println("转换成功: " + num1);

            int num2 = Integer.parseInt(invalid); // 会报错
            System.out.println("转换成功: " + num2);

        } catch (NumberFormatException e) {
            System.out.println("异常信息: " + e.getMessage());
        }

        try {
            int num3 = Integer.parseInt(decimal); // 也会报错
            System.out.println("转换成功: " + num3);
        } catch (NumberFormatException e) {
            System.out.println("异常信息: " + e.getMessage());
        }
    }
}

运行结果

txt 复制代码
转换成功: 123
异常信息: For input string: "abc"
异常信息: For input string: "123.45"

可以看到,只有 "123" 是合法整数,其他的输入都会抛异常。

为什么会出现 NumberFormatException?

  • 输入不是数字 :例如 "hello",根本无法解析成数字。
  • 类型不匹配 :例如 "123.45"Integer.parseInt() 来解析,因为 123.45 是小数,不是整数。
  • 隐藏的非法字符 :例如字符串里有空格、换行、中文数字("123"),看起来是数字,其实不是。

解决方案

1. 输入校验

在转换前,先校验输入是否是合法的数字。比如用正则表达式:

java 复制代码
public static boolean isNumeric(String str) {
    return str != null && str.matches("\\d+");
}

public static void main(String[] args) {
    String input = "123a";
    if (isNumeric(input)) {
        int num = Integer.parseInt(input);
        System.out.println("转换成功: " + num);
    } else {
        System.out.println("输入不是合法数字: " + input);
    }
}

运行结果:

txt 复制代码
输入不是合法数字: 123a

2. 使用异常捕获

如果无法保证输入一定是数字,可以用 try-catch 来兜底:

java 复制代码
public static Integer safeParseInt(String input) {
    try {
        return Integer.parseInt(input);
    } catch (NumberFormatException e) {
        return null; // 或者返回默认值
    }
}

这种方式适合用户输入不确定时,比如表单提交、配置文件解析。

3. 选择合适的数据类型

如果输入可能是小数,就不要用 Integer.parseInt(),而是用 Double.parseDouble()BigDecimal

java 复制代码
String input = "123.45";
double value = Double.parseDouble(input);
System.out.println("转换结果: " + value);

输出:

txt 复制代码
转换结果: 123.45

实际场景

  1. 读取配置文件

    很多时候我们在 application.properties 或者数据库里存储的配置值是字符串,读取后需要转成数字。此时一定要做好校验,否则一旦配置写错就会导致应用启动失败。

  2. 处理用户输入

    表单提交的数字其实是字符串,比如 " 123 ",如果没有 trim 就可能报错。解决办法是先做 input.trim(),然后再解析。

  3. 外部接口返回

    调用第三方接口时,对方可能返回 "null""""N/A" 之类的字符串,如果直接 parseInt(),必然抛异常。

    这种情况要么提前判断,要么用 Optional 封装。

总结

NumberFormatException 其实就是在告诉我们:"这个字符串没办法转成你要的数字"。

解决的核心思路有三点:

  1. 在转换之前做 输入校验
  2. 如果输入不确定,用 try-catch 保底
  3. 根据业务场景选择合适的 数据类型IntegerDoubleBigDecimal)。

掌握了这些方法后,下次你再遇到 NumberFormatException,就能快速定位并解决问题,而不是一脸懵。

相关推荐
侠客行03176 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪6 小时前
深入浅出LangChain4J
java·langchain·llm
灰子学技术8 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
老毛肚8 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎8 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
二十雨辰8 小时前
[python]-AI大模型
开发语言·人工智能·python
Yvonne爱编码8 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚8 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂8 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
pas1369 小时前
41-parse的实现原理&有限状态机
开发语言·前端·javascript