java中equals方法通过按业务语义精确控制字段参与比较来提升逻辑准确性,避免默认引用比较或遗漏关键属性;需重写以指定关键字段、处理null安全、类型校验及浮点数误差判断。

Java 中 equals 方法本身不“提升精度”,而是通过**按业务语义精确控制字段参与比较**,避免默认引用比较或遗漏关键属性,从而让“相等”的判定更符合真实需求。所谓“精度”,实为逻辑准确性——不是数值小数点后几位,而是该比什么、不该比什么、怎么比才合理。
只比关键字段,排除干扰项
默认的 equals(继承自 Object)只比较内存地址;若未重写,两个内容完全相同的对象也会判为不等。重写后可自主决定哪些字段影响相等性:
- 用户登录校验中,只需比
username和email,忽略lastLoginTime或id(数据库自增主键) - 订单比对时,可能只关注
orderNo和amount,跳过createdAt或statusVersion - DTO 传输对象中,剔除临时计算字段(如
formattedPrice)、敏感字段(如passwordHash)
处理 null 安全与类型校验
直接调用 field.equals(other.field) 易触发空指针异常。规范写法应前置防护:
- 用
Objects.equals(a, b)替代a.equals(b),自动处理任一参数为null的情况 - 先判断
obj == null或getClass() != obj.getClass(),防止类型转换异常 - 基本类型字段(如
int、boolean)直接用==,无需equals
应对浮点与高精度数值的特殊逻辑
字段含 float/double 时,不能直接 == 或 equals:
- 改用误差范围判断:
Math.abs(f1 - f2) - 字段为
BigDecimal时,必须用compareTo() == 0,而非equals()(后者会对比精度,new BigDecimal("3")与new BigDecimal("3.00")判为不等) - 若字段是封装类(如
Float),需先判null,再转原始值比较
保持 equals 与 hashCode 逻辑一致
字段级比较的改动必须同步反映到 hashCode 中,否则放入 HashSet 或作 HashMap key 时会失效:
- 若
equals只用了name和age,则hashCode也仅基于这两个字段计算 - 推荐用
Objects.hash(name, age)生成哈希码,简洁且防空 - 避免在
hashCode中引入可变字段(如lastModified),否则对象加入集合后修改该字段会导致无法查找
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











