equals重写须遵循自反性、对称性、传递性、一致性和非空性五原则,确保逻辑相等性;同时必须重写hashCode,因HashSet/HashMap先通过hashCode定位桶,再用equals精确比较,若不协同重写将导致去重失败或查找丢失。

不用死记硬背,抓住逻辑主线就自然记牢。
equals 方法重写的5条核心原则
这五条不是孤立条款,而是对象“相等”这个概念在数学和工程上的基本要求:
-
自反性:自己必须等于自己。比如
user.equals(user)一定为true,否则逻辑崩塌。 -
对称性:你认我,我也得认你。如果
a.equals(b)是true,那b.equals(a)也必须是true;用instanceof判断类型容易破坏这点(子类调父类 equals 可能返回 true,反过来却 false)。 -
传递性:A 等于 B、B 等于 C,那 A 就该等于 C。否则集合去重或排序会出错,比如
HashSet或TreeSet行为异常。 -
一致性:只要对象内容不变,无论调多少次
equals,结果不能变。不能今天相等、明天不等——这会让缓存、哈希表彻底失效。 -
非空性:任何对象调用
obj.equals(null)都必须返回false;这是安全底线,避免 NPE。
重写时最关键的三步检查
面试官常让你现场写,记住这个骨架,填属性名就能过:
- 先判断是不是同一个对象:
if (this == o) return true; - 再判空 + 类型严格匹配:
if (o == null || getClass() != o.getClass()) return false;(不用instanceof,保对称) - 最后强转 + 属性逐个比较:
return Objects.equals(name, other.name) && this.age == other.age;
为什么必须连带重写 hashCode
这不是凑数规定,是哈希结构的底层机制决定的:
立即学习“Java免费学习笔记(深入)”;
-
HashSet/HashMap先靠hashCode()定位桶位置; - 只有
hashCode相同,才会进一步调equals()做精确比对; - 如果只改
equals不改hashCode,两个逻辑相等的对象可能被分到不同桶里,add两次、get找不到——业务直接出 bug。
最省心又规范的写法(JDK 7+)
直接用 Objects 工具类,既安全又满足全部原则:
-
equals里用Objects.equals(a, b)(自动处理 null) -
hashCode里用Objects.hash(a, b, c)(参数顺序和equals保持一致) - 两处参与比较的字段必须完全相同,缺一不可。


















