1、==、equals、hashCode底层原理?重写场景?

张开发
2026/4/20 8:20:14 15 分钟阅读

分享文章

1、==、equals、hashCode底层原理?重写场景?
目录一、核心定义存在意义基础作用1. 是什么为什么存在作用2. equals()是什么为什么存在作用3. hashCode()是什么为什么存在作用二、底层原理原生源码JVM层级1. 底层原理2. equals() 底层原理原生Object源码3. hashCode() 底层原理三、三者联动规范强制底层契约四、重写场景精准业务落地1. 什么时候必须重写 equals()2. 什么时候必须重写 hashCode()3. 什么时候不用重写4. 补充String/JDK常用类现状一、核心定义存在意义基础作用1.是什么Java原生运算符语法级比较符号不依赖任何方法实现。为什么存在JVM需要一套底层原生机制直接判定两个变量内存指向/基础值是否完全一致。作用比较基本数据类型判断栈中存储的字面数值是否相等比较引用数据类型判断两个引用变量**堆内存地址对象指针**是否指向同一个对象。2.equals()是什么Object类中定义的public boolean equals(Object obj)实例方法所有类默认继承。为什么存在仅能比内存地址业务中需要比对对象内容/属性逻辑相等而非同一个内存对象因此提供可自定义的逻辑比较入口。作用实现业务层面的对象内容相等判定开发者可重写该方法自定义相等规则。3.hashCode()是什么Object类中定义的public native int hashCode()本地方法返回对象int类型哈希码。为什么存在配合哈希表集合HashMap/HashSet/HashTable实现高效存取、快速判重哈希表先靠哈希码定位桶再用equals精准比对降低比对开销。作用为对象生成固定哈希编码确定哈希表存储桶位置约束规范两个equalstrue的对象必须哈希码相同减少equals全量比对次数。二、底层原理原生源码JVM层级1.底层原理基本类型byte/short/int/long/float/double/char/boolean变量直接在虚拟机栈存真实数值直接比对栈内两个数值的二进制数据完全一致则返回true。2. 引用类型变量在栈中存对象堆内存的地址指针直接比对两个指针的内存地址值只有指向堆中同一个对象才返回true。无任何方法调用纯JVM指令级地址/数值比对。2.equals()底层原理原生Object源码Object类原生源码public boolean equals(Object obj) { return (this obj); }底层原生实现直接复用地址比对。未重写时equals和比对逻辑完全一致只比内存地址重写后开发者自定义属性比对逻辑不再依赖地址比对。3.hashCode()底层原理原生是native本地方法由JVM底层实现非Java代码编写JVM默认生成规则基于对象堆内存地址、对象头哈希字段、随机数、对象生命周期生成int整数原生规则同一个对象多次调用hashCode返回值始终一致不同对象大概率哈希码不同存在哈希碰撞4.哈希表工作底层存元素计算hashCode→取模定位哈希桶→桶内用equals逐个比对判重先比hashCode不同直接判不相等相同再执行equals精准校验。三、三者联动规范强制底层契约若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()只要重写了equals()就必须同步重写hashCode()专属场景对象要放入所有哈希结构集合HashMap、HashSet、LinkedHashMap等不重写会导致内容相等的两个对象hashCode不同存到不同哈希桶集合判重失效、get(key)获取不到数据、去重失败。3. 什么时候不用重写实体类仅做数据传输无需比对相等、不存入哈希集合枚举类、基础包装类Integer/String已JDK底层重写完毕直接用只靠地址比对就能满足所有业务逻辑。4. 补充String/JDK常用类现状String、Integer、Long、BigDecimal等JDK类已原生重写equals比字符/数值内容 重写hashCode按内容生成哈希码直接使用即可满足内容相等比对。

更多文章