✅ 1. 语法与默认行为

public boolean equals(Object obj)   // Object 类中的实现
  • 默认实现
    仅比较「引用地址」,即 this == obj 的结果。
    因此,对于两个 new 出来的对象,即使内部字段完全相同,也返回 false

✅ 2. 何时需要重写

只要业务上需要「按字段内容」判断是否相等(如 StringInteger、自定义实体),就必须重写 equals()


✅ 3. 重写规则(4 条铁律)

原则 说明
自反性 x.equals(x) 必为 true
对称性 x.equals(y)y.equals(x) 结果一致
传递性 x.equals(y)y.equals(z)x.equals(z)
一致性 对象未变,多次调用结果必须相同
非空性 任何非空对象,x.equals(null) 必须为 false

✅ 4. 正确重写模板(含 hashCode

@Override
public boolean equals(Object o) {
    if (this == o) return true;                 // 1. 同一引用
    if (!(o instanceof User)) return false;     // 2. 类型检查
    User other = (User) o;
    return Objects.equals(this.id, other.id)    // 3. 关键字段比较
        && Objects.equals(this.name, other.name);
}

@Override
public int hashCode() {
    return Objects.hash(id, name);              // 4. 同时重写 hashCode
}

⚠️ 重写 equals 必须同时重写 hashCode,否则 HashMap/HashSet 会出错。


✅ 5. 与 == 的区别

比较符 比较内容 适用场景
== 引用地址 基本类型或判空
equals 对象「内容」 引用类型业务相等判断

✅ 6. 空指针安全写法

// 推荐:使用 java.util.Objects 工具类
boolean same = Objects.equals(a, b);   // null-safe,不会抛 NPE

✅ 7. 高频坑点汇总

  1. 只重写 equals 不写 hashCode → Hash 集合行为异常。
  2. 使用 getClass() 与 instanceof 混用 → 破坏对称性/传递性。
  3. 在 equals 里修改字段 → 一致性被破坏。
  4. 把 null 强转后比较字段 → 必抛 NPE。

✅ 8. 一句话总结

默认 equals 比地址,业务相等需重写;重写同时写 hashCode,用 Objects.equals 防 NPE。