同事昨天甩过来一段日志,说线上金额算错了一位小数。翻代码发现源头是从配置文件读出来的字符串没转干净,Integer.parseInt 碰到带空格的「 12 」直接抛 NumberFormatException,异常又被 catch 吞掉,字段就留了默认值 0。

parseInt 和 valueOf 差在哪

parseInt 返回的是基本类型 int,valueOf 返回 Integer 对象。循环几百万次做数值计算,前者不产生对象,省一点 GC。valueOf 底层其实也调了 parseInt,只是多包了一层,好处是可以直接扔进集合。

带小数和空格的字符串怎么处理

Double.parseDouble 能认小数点,但不认全角数字,也不认千分位逗号。从 Excel 或 CSV 里读出来的 1,234 直接转必然报错,得先把逗号去掉。前后空格用 trim,全角空格 U+3000 用 trim 是去不掉的,得自己 replaceAll。

转不了的时候给个默认值

  • 先判断再转:用正则 ^-?[0-9]+$ 过一遍再 parseInt,脏数据当场挡掉。
  • try-catch 兜底:解析失败返回默认值,别让异常冒到上层业务。
  • 大数别用 int:超过 21 亿的走 Long.parseLong 或 BigInteger,否则默默溢出。

一段能直接抄的工具方法

public static int toInt(String s, int def) { if (s == null) return def; s = s.trim(); if (s.isEmpty()) return def; try { return Integer.parseInt(s); } catch (NumberFormatException e) { return def; } }

要去千分位逗号,就在 try 之前加一步把非数字字符剔除,注意别把负号也删了。

最后说个取舍:业务入口处做一次严格校验,比在每个使用点都写 try-catch 省心;但像日志、埋点这种脏数据多、又不能让流程中断的地方,带默认值的宽松转换反而更合适。