Java中equals方法必须严格遵循自反性、对称性、传递性、一致性、非空性五原则,且与hashCode保持一致;典型场景是自定义类按内容而非引用判断相等,重写时须判空、类型校验、字段逐一对比,并确保参与equals的字段全部纳入hashCode计算。

Java 中 equals 方法要逻辑正确,核心是严格遵循 自反性、对称性、传递性、一致性、非空性 这五条约定,同时必须与 hashCode 保持一致。光写 a == b || a.equals(b) 不够,也不推荐直接用 IDE 自动生成而不理解原理。
必须重写 equals 的典型场景
当你自定义类(如 User、Point)需要按「内容相等」而非「引用相等」来判断时,就必须重写 equals。比如两个 User 对象 id 和 name 都相同,就应视为相等——这是业务语义,Object 默认的引用比较无法满足。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
标准实现步骤(缺一不可)
-
先判 null 和类型:用
if (obj == null || getClass() != obj.getClass()) return false;。用getClass()而非instanceof,避免子类与父类比较时破坏对称性(例如new User().equals(new Admin())若用instanceof可能返回 true,但反过来不成立) -
强制类型转换:确认类型安全后,转为本类类型,如
User other = (User) obj; -
逐字段比较:基本类型用
==,引用类型用Objects.equals(a, b)(它会自动处理 null);注意浮点数慎用==,优先用Double.compare等工具方法 - 所有参与 equals 判断的字段,必须同样参与 hashCode 计算:否则违反「相等对象必须有相同 hash code」约定,导致放入 HashMap/HashSet 时行为异常
常见错误避坑
错误1:只重写 equals,不重写 hashCode → HashMap 中可能找不到已存对象。
错误2:在 equals 中修改对象状态(比如懒加载字段)→ 破坏一致性,同一对象多次调用结果可能不同。
错误3:用 instanceof 判类型且类可被继承 → 子类实例可能和父类实例不对称相等。
错误4:字段比较漏掉 null 检查,或用 str1.equals(str2) 但 str1 为 null → 抛 NullPointerException。
推荐做法:用 Objects.equals + Lombok 或 IDE 辅助
手写易错,建议:
• 使用 Objects.equals(field1, other.field1) && Objects.equals(field2, other.field2) 替代手动 null 判断
• 开发中启用 Lombok 的 @EqualsAndHashCode(默认只包含非 static、非 transient 字段),并显式指定 include 或 exclude 字段
• 若用 IntelliJ,生成 equals 时勾选「Use 'java.util.Objects.equals()'」并确认字段选择无误

















