应使用compareto()判断bigdecimal数值是否相等,即a.compareto(b) == 0;因为equals()同时比较数值、scale和符号,而业务中通常只关心数学值是否相等。

用 compareTo() 替代 equals() 判断 BigDecimal 数值是否相等,核心就一条:调用 a.compareTo(b) == 0,而不是 a.equals(b)。这是因为 equals() 会同时校验数值和精度(scale),而业务中我们通常只关心“值是不是一样”。
为什么 equals 不适合判断数值相等
equals() 方法在 BigDecimal 中设计为“对象完全一致”的判定,它严格比较三要素:数值、小数位数(scale)、符号。哪怕只是字符串构造时多写了两个零,也会导致不等:
-
new BigDecimal("10.0")和new BigDecimal("10.00")——equals()返回 false -
new BigDecimal("0.0")和new BigDecimal("-0.0")——equals()也返回 false(正零 ≠ 负零)
compareTo 的正确用法
compareTo() 只比数值大小,自动忽略 scale 差异,天然适配金融、计费等对“数学相等”有要求的场景:
- 返回 0 → 两数数学上相等(如
"5.00"和"5.0") - 返回 负数(通常是 -1)→ 当前对象更小
- 返回 正数(通常是 1)→ 当前对象更大
常用写法示例:
if (amount.compareTo(BigDecimal.ZERO) == 0) { /* 金额为零 */ }<br>if (price.compareTo(minPrice) >= 0) { /* 价格不低于最低价 */ }
实际开发中的关键细节
-
避免空指针:compareTo 前务必确保两个对象非 null,否则抛
NullPointerException -
不要依赖返回值一定是 ±1:规范只要求负/零/正,具体值由实现决定;所以只用
== 0、> 0、判断,别硬写 <code>== 1 -
初始化推荐用字符串:如
new BigDecimal("0.1"),避免new BigDecimal(0.1)引入 double 二进制误差
什么时候还能用 equals
只有当你明确需要“值 + 精度 + 符号”三者完全一致时才用 equals(),比如:
- 序列化后反序列化校验
- 配置项或规则引擎中要求“必须是带两位小数的金额格式”
- 单元测试中验证构造结果是否与预期字符串完全匹配










