目录
一、核心定义&存在意义&基础作用
1. ==
是什么
为什么存在
作用
2. equals()
是什么
为什么存在
作用
3. hashCode()
是什么
为什么存在
作用
二、底层原理(原生源码+JVM层级)
1. == 底层原理
2. equals() 底层原理(原生Object源码)
3. hashCode() 底层原理
三、三者联动规范(强制底层契约)
四、重写场景(精准业务落地)
1. 什么时候必须重写 equals()
2. 什么时候必须重写 hashCode()
3. 什么时候不用重写
4. 补充:String/JDK常用类现状
一、核心定义&存在意义&基础作用
1.==
是什么
为什么存在
作用
- 比较基本数据类型:判断栈中存储的字面数值是否相等;
- 比较引用数据类型:判断两个引用变量**堆内存地址(对象指针)**是否指向同一个对象。
2.equals()
是什么
为什么存在
作用
3.hashCode()
是什么
为什么存在
作用
- 为对象生成固定哈希编码,确定哈希表存储桶位置;
- 约束规范:两个equals=true的对象,必须哈希码相同;减少equals全量比对次数。
二、底层原理(原生源码+JVM层级)
1.==底层原理
- 基本类型(byte/short/int/long/float/double/char/boolean):
2.equals()底层原理(原生Object源码)
- 未重写时:equals和==比对逻辑完全一致,只比内存地址;
- 重写后:开发者自定义属性比对逻辑,不再依赖地址比对。
3.hashCode()底层原理
- 原生是native本地方法,由JVM底层实现,非Java代码编写;
- JVM默认生成规则:基于对象堆内存地址、对象头哈希字段、随机数、对象生命周期生成int整数;
- 原生规则:
- 同一个对象,多次调用hashCode,返回值始终一致;
- 不同对象,大概率哈希码不同(存在哈希碰撞);
4.哈希表工作底层:
三、三者联动规范(强制底层契约)
- 若a.equals(b) = true → 必须保证 a.hashCode() == b.hashCode();
- 若a.hashCode() != b.hashCode() → 必须保证 a.equals(b) = false;
- 若a.hashCode() == b.hashCode() → a.equals(b)可true可false(哈希碰撞);
- 只重写equals不重写hashCode:违反契约,HashMap/HashSet会出现逻辑异常(相同内容对象存重复、取不出)。
四、重写场景(精准业务落地)
1. 什么时候必须重写equals()
- 自定义实体类(User/Order/Student等),需要按属性判定对象逻辑相等,而非地址相等;
- 对象需要存入HashSet、作为HashMap的key,必须重写equals做内容精准判重;
- 业务需求:两个对象所有核心字段一致即判定为同一个业务数据。
2. 什么时候必须重写hashCode()
- 内容相等的两个对象,hashCode不同,存到不同哈希桶;
- 集合判重失效、get(key)获取不到数据、去重失败。
3. 什么时候不用重写
- 实体类仅做数据传输,无需比对相等、不存入哈希集合;
- 枚举类、基础包装类(Integer/String已JDK底层重写完毕,直接用);
- 只靠==地址比对就能满足所有业务逻辑。