stripTrailingZeros() 返回新对象且不改变原值,需显式赋值;仅简化标度、不损失精度;须配合toPlainString()才能确保无尾零且无科学计数法输出。

stripTrailingZeros() 不会改变原始 BigDecimal 对象
stripTrailingZeros() 返回的是一个新对象,原 BigDecimal 不变。这是最容易忽略的一点——很多人调用后没重新赋值,结果打印还是带零的值。
比如:
BigDecimal a = new BigDecimal("100.00");
a.stripTrailingZeros(); // 没有赋值给 a 或其他变量
System.out.println(a); // 输出 100.00,不是 100
正确做法是显式接收返回值:
a = a.stripTrailingZeros();- 或直接用于输出:
System.out.println(a.stripTrailingZeros());
stripTrailingZeros() 只处理标度(scale),不改变数值精度
它只移除末尾的零小数位,比如 123.4500 → 123.45,但不会把 123.0 变成 123(即 scale 从 1 变成 0),而是变成 123(scale=0)——这其实是同一回事。关键在于:它只简化表示形式,不损失精度,也不做四舍五入。
常见误解场景:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
-
new BigDecimal("0.000").stripTrailingZeros()→0(scale=0) -
new BigDecimal("1.00").multiply(new BigDecimal("2.0"))默认可能得2.000,再调stripTrailingZeros()得2 - 但如果中间用了
setScale(2, RoundingMode.HALF_UP),再 strip 就只是清理那两个零,和原始精度无关
和 toString()、toPlainString() 配合使用才能稳定显示无零格式
stripTrailingZeros() 本身不控制字符串输出格式。如果你直接用 toString(),对某些值(如科学计数法范围内的数)仍可能触发指数形式,例如 new BigDecimal("100000000000000").stripTrailingZeros().toString() 可能输出 1E+14。
要确保“纯数字无尾随零且不走科学计数”,必须搭配 toPlainString():
- ✅ 安全写法:
val.stripTrailingZeros().toPlainString() - ❌ 风险写法:
val.stripTrailingZeros().toString()(可能含 E) - ⚠️ 注意:
toPlainString()总是返回完整十进制表示,但对极大/极小数可能很长,别在日志里无节制打印
stripTrailingZeros() 在 equals() 和 hashCode() 中不产生影响
两个逻辑相等的 BigDecimal,即使一个调过 stripTrailingZeros()、另一个没调,equals() 依然返回 true。因为 BigDecimal.equals() 比较的是数值 + 标度(即 1.0 ≠ 1.00),但 stripTrailingZeros() 的返回值已调整标度,所以它和原值数值相同、标度也已归一化。
不过要注意:
-
new BigDecimal("1.0").equals(new BigDecimal("1.00"))→false -
new BigDecimal("1.0").stripTrailingZeros().equals(new BigDecimal("1.00").stripTrailingZeros())→true - 如果要做 Map key 或 Set 元素去重,建议统一先
stripTrailingZeros()再放入,避免标度差异导致重复
实际用的时候,最常漏掉的就是赋值和 toPlainString() 这两步。尤其在拼接日志、生成 JSON 字段、或对接前端要求“整数就写整数”的接口时,光调 stripTrailingZeros() 不够,不转成 plain 字符串,前端看到的还是 "100.00"。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










