system.identityhashcode() 返回对象基于内存地址的唯一哈希值,不依赖重写的 hashcode() 方法;用于引用相等判断、调试区分相同内容的不同实例及避免哈希干扰,对 null 调用抛 npe,非真实地址但稳定高效。

System.identityHashCode() 是 Java 中获取对象“原始哈希码”的标准方式——它不依赖对象是否重写了 hashCode() 方法,而是基于对象在 JVM 中的内存地址(或其稳定衍生物)生成一个唯一整数值。
为什么需要 identityHashCode?
当对象重写了 hashCode()(比如 String、ArrayList),它的哈希值反映的是内容逻辑;而 identityHashCode 保证同一对象实例始终返回相同值,且不同对象(即使内容相同)大概率返回不同值。这在以下场景很关键:
- 实现基于引用相等(
==)的缓存或映射(如弱引用缓存) - 调试时区分两个内容相同但不同的对象实例
- 在自定义哈希结构中避免因重写
hashCode()导致的哈希碰撞干扰
基本用法:直接调用即可
只需传入任意非空对象引用:
```javaObject obj = new Object();
int hash = System.identityHashCode(obj); // 返回一个 int,例如 1923456789
```
⚠️ 注意:对 null 调用会抛出 NullPointerException,使用前需判空(若可能为 null,可约定用 0 或其他哨兵值)。
和普通 hashCode() 的对比示例
看这段代码就清楚区别:
```javaString s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1.hashCode() == s2.hashCode()); // true(内容相同 → 哈希相同)
System.out.println(System.identityHashCode(s1) == System.identityHashCode(s2)); // false(不同实例 → 原始哈希不同)
```
即使 s1.equals(s2) 为 true,它们的 identityHashCode 几乎一定不同——这才是“对象身份”的哈希体现。
注意事项与常见误区
- 不是内存地址本身:JVM 不暴露真实地址(出于安全和 GC 移动性),identityHashCode 是 JVM 内部生成的、生命周期内稳定的整数标识
- 不保证跨 JVM 或重启后一致:每次运行、不同 JVM 实例中,同一对象的 identityHashCode 可能不同
-
不适用于数组的元素比较:对数组调用得到的是该数组对象的 identity 哈希,不是其中元素的;若想对数组内容做 identity 比较,需逐个调用
System.identityHashCode(arr[i]) -
性能开销极低:底层是 JVM 内建操作,比多数重写的
hashCode()还快










