会,Double.parseDouble() 直接抛出 NumberFormatException;它只接受纯数字格式(可选正负号、小数点、科学计数法),对空格、逗号、单位、全角字符等一律拒绝,且不修复、不默认、不协商。

Double.parseDouble() 会直接抛出 NumberFormatException 吗?
会,而且非常干脆。只要字符串里有哪怕一个非数字字符(空格、逗号、中文符号、单位如“kg”、“%”),或者内容是 "NaN"、"Infinity"(大小写敏感)、空字符串、null,它就立刻炸——不尝试修复,不返回默认值,也不给你商量余地。
- 常见错误现象:
NumberFormatException: For input string: "12.34 "(末尾空格)、"1,234.56"(千分位逗号)、"12.34元" - 它只接受纯数字格式:可选正负号 + 数字 + 可选小数点 + 可选数字 + 可选科学计数法(如
"1.23e-4") - 不处理本地化格式(比如德语用逗号作小数点),也不识别 Unicode 全角数字
想安全转换,必须自己预处理字符串
不能把清洗逻辑交给 Double.parseDouble(),得在调用前把字符串“擦干净”。核心思路是:先删干扰,再验结构,最后转。
- 去除首尾空白:
str.trim()是必须的,否则" 12.34 "直接失败 - 移除千分位逗号:用
str.replace(",", ""),但注意别误删小数点前的逗号(其实逗号只可能在整数部分,所以放心替) - 过滤非数字字符(谨慎!):如果确定只有数字、小数点、正负号、e/E,可用正则
str.replaceAll("[^\d.-eE]", "");但若原始字符串含“~”“±”等符号,这种粗暴过滤会掩盖数据问题,不如先日志报警 - 验证是否为空或仅含符号:
str.trim().length() == 0 || str.trim().equals("-") || str.trim().equals("+"),这些都该提前拒绝
为什么不用 Double.valueOf() 或 new Double()?
Double.valueOf() 内部就是调 Double.parseDouble(),只是多包了一层 Double 对象;而 new Double(String) 已在 Java 9+ 被弃用,且行为完全一致。三者在异常类型、精度、空值处理上毫无区别。
- 性能上:
Double.parseDouble()最轻量,返回基本类型double,避免装箱开销 - 兼容性上:所有 JDK 版本都稳定支持,无迁移风险
- 唯一差异点:如果真需要
null安全(比如数据库字段可能为null),得自己判空,Double.parseDouble(null)必然 NPE
实际转换时,try-catch 是唯一兜底方式
没有“静默失败”选项。你必须显式捕获 NumberFormatException,并决定是抛自定义异常、返回默认值(如 0.0)、还是记录后跳过。
- 别用
try-catch包裹大段业务逻辑,只围住Double.parseDouble(str)这一行 - 日志中务必打印原始字符串:
log.warn("Failed to parse double: '{}'", str),否则排查时两眼一抹黑 - 如果默认值有意义(比如“未填写”视为 0),可以写成:
double value; try { value = Double.parseDouble(str.trim().replace(",", "")); } catch (NumberFormatException e) { value = 0.0; }
浮点数字符串转换真正麻烦的从来不是函数本身,而是你永远不知道上游传来的字符串里藏了多少个看不见的空格、全角字符、隐藏控制符,或者根本就是前端随手拼出来的 "price: " + price。预处理和异常捕获不是可选项,是必填项。










