java包装类不处理大数值,而是暴露精度截断问题;long安全范围为±9,223,372,036,854,775,808,超出抛numberformatexception;double整数精度仅至2⁵³,超限静默丢位;关键字段应选用biginteger或bigdecimal。

Java 中包装类本身不“处理”大数值,而是帮你暴露和管理精度截断问题。真正要防的不是转换动作本身,而是把 超出 Long 范围的整数硬塞进 long、或把 超过 2⁵³ 的整数用 Double 表示——这时截断是静默发生的,不报错但结果已错。
认清 Long 和 Double 的真实能力边界
Long 是 64 位有符号整数,安全范围是 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。一旦字符串表示的数字超出这个范围,Long.parseLong() 或 Long.valueOf() 直接抛 NumberFormatException,这是好事——它让你立刻发现输入越界。
Double 看似能表示极大数(±1.8×10³⁰⁸),但整数精度只到 2⁵³(约 9×10¹⁵)。比如 Double.valueOf("9007199254740993") 返回的是 9007199254740992.0,末位直接丢弃,且不提示。
- 用
Long.parseLong()解析 ID、计数器等整数时,如果原始字符串长度 ≥ 19 位,先校验是否在范围内,或改用BigInteger - 别用
Double存用户 ID、订单号、时间戳毫秒值——这些必须精确,哪怕数值很大 - 若字符串来自前端或外部系统,不能假设它“看起来像整数就一定在 long 范围内”
字符串转数值:用对方法,别跳过异常处理
所有 parseXXX() 和 valueOf() 方法对非法格式或溢出都抛运行时异常,这不是缺陷,是设计使然。关键是要主动捕获,而不是让 NPE 或 NumberFormatException 漏到上层。
- 永远用
try-catch包裹Long.parseLong(str)和Double.parseDouble(str) - 不要用
(long) Double.parseDouble(str)这种组合——Double 先失真,再转 long,错误叠加 - 需要默认值?自己封装工具方法,例如:
Long safeParseLong(String s, long def),内部 catch 后返回 def - 空或空白字符串必须提前判空,否则
valueOf(null)抛NullPointerException
运算中避免拆箱引发的隐式截断链
包装类参与算术运算会自动拆箱,但 null 拆箱即 NPE;更隐蔽的是,Double 对象参与计算后赋给 long 变量,中间可能已发生浮点截断。
-
Double d = 1234567890123456789.0; long l = d.longValue();→ 结果可能是错的,因为 Double 已无法精确表示该整数 - 涉及金额、ID、版本号等关键字段,禁止用
Double做中间存储或计算 - 从集合取值(如
List<double></double>)后,别直接用于比较或计算,先确认非 null,再评估是否需转BigDecimal - 用
Optional.ofNullable(d).map(Double::doubleValue).orElse(0.0)替代裸拆箱,至少把空值逻辑显性化
该换 BigDecimal 或 BigInteger 时,别硬扛
当业务明确要求“不能丢一位数字”,就不再属于包装类职责范围。Long/Double 是通用数值载体,不是高精度解决方案。
- 金融计算、税率、余额变动——一律用
BigDecimal,构造时用字符串:new BigDecimal("123.45"),不用new BigDecimal(123.45)(后者从 double 构造,double 本身已失真) - 超长 ID(如雪花 ID 19 位)、哈希值、大质数运算——用
BigInteger,支持任意长度整数运算 - 前后端传 ID:后端序列化时统一转 String,前端收字符串,避免 JS 的
Number精度陷阱 - 数据库字段类型要与 Java 类型对齐:bigint → Long 或 String,decimal → BigDecimal,别用 double 存金额
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











