System.identityHashCode()返回对象JVM身份哈希码,基于对象头中存储的原始标识,完全不受类重写hashCode()影响;适用于调试、IdentityHashMap及区分同内容不同实例等场景。

System.identityHashCode() 的作用就是返回对象在 JVM 中的“身份哈希码”,它与对象的内存地址相关(具体是基于对象首次被分配时的地址或内部 ID 生成),**完全独立于类是否重写了 hashCode() 方法**。因此,只要调用它,就天然不受重写影响。
它为什么不会受重写 hashCode 影响?
因为 identityHashCode 是 JVM 层面为每个对象分配的唯一标识码,在对象创建时就已确定,存储在对象头中(如 mark word 的一部分)。而 obj.hashCode() 是运行时动态调用该对象所属类的 hashCode() 实例方法——如果类重写了它,就会执行重写逻辑;没重写则默认调用 Object.hashCode(),后者底层才等价于 System.identityHashCode(obj)。
怎么正确使用它?
- 直接传入任意对象引用,例如:
System.identityHashCode(str)、System.identityHashCode(list) - 即使对象来自重写了
hashCode()的类(如String、ArrayList、自定义类),结果也始终反映其“身份”,而非业务语义 - 对
null调用会返回 0(注意判空) - 同一对象在 JVM 生命周期内,多次调用该方法返回值一定相同(除非发生 GC 移动且 JVM 使用了带压缩指针的策略,但 identityHashCode 仍保证唯一性和稳定性)
和普通 hashCode() 对比的典型例子
假设你有:
class Person {
String name;
public Person(String name) { this.name = name; }
@Override public int hashCode() { return name != null ? name.hashCode() : 0; }
}那么:
-
new Person("Alice").hashCode()→ 返回"Alice".hashCode()(字符串内容哈希) -
System.identityHashCode(new Person("Alice"))→ 每次新建对象都不同,反映的是这个新对象的“身份”,与名字无关 - 两个
new Person("Alice")实例,hashCode()相同,但identityHashCode()一定不同
适用场景提醒
它适合用于:
- 调试时区分“内容相同但不是同一个对象”的情况(比如深拷贝前后)
- 实现基于对象身份的缓存或映射(如
IdentityHashMap) - 排查哈希冲突、集合去重异常时验证是否真为同一对象
不适用于需要按业务逻辑比较相等性的场景——那应该用 equals() + hashCode() 配合。










