System.identityHashCode 的核心用途是获取对象的唯一身份标识哈希值,始终基于JVM对对象实例的底层识别(如内存地址或唯一ID),不受类是否重写hashCode()影响;而Object.hashCode()是可重写的实例方法,基于对象内容计算,服务于逻辑相等性与哈希集合查找。

System.identityHashCode 的核心用途是获取对象的“身份标识哈希值”,它不依赖类是否重写了 hashCode(),始终反映 JVM 对该对象实例的底层识别方式;而 Object.hashCode() 是一个可被覆盖的普通方法,返回的是业务逻辑意义上的哈希值,常用于集合查找与去重。
identityHashCode 保证对象身份唯一性
即使两个对象内容完全相同、甚至属于同一类且重写了 hashCode(),只要它们是不同实例(内存中不同地址),System.identityHashCode 就会返回不同值。这在调试、缓存键设计、或需要区分“相等但非同一”的对象时非常关键。
- 适合判断两个引用是否指向同一个对象实例(类似 == 的语义,但可用于无法直接比较引用的场景,比如序列化后反序列化前)
- 在对象未重写 hashCode() 时,它的值通常和 Object.hashCode() 相同;一旦重写,二者就可能完全不同
- JVM 保证同一个对象在整个生命周期内 identityHashCode 不变(即使发生 GC 移动,JVM 内部会维护映射)
hashCode() 服务于逻辑一致性
Object.hashCode() 的设计目标是配合 equals() 实现“相等对象必须有相同哈希码”。String、Integer 等类都重写了它,使其基于内容而非地址计算。因此,它适合用在 HashMap、HashSet 等基于哈希的集合中。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 若 a.equals(b) 为 true,则 a.hashCode() == b.hashCode() 必须成立(这是契约)
- 它不保证唯一性:不同对象可能算出相同 hash 值(哈希碰撞)
- 调用 null.hashCode() 会抛出 NullPointerException,而 System.identityHashCode(null) 安全返回 0
典型使用场景对比
当你要确认“是不是同一个对象”时,用 identityHashCode;当你关心“值是否相等、能否放进同一个哈希桶”时,用 hashCode()。
- 监控工具中追踪对象创建/销毁:记录 identityHashCode 可避免因重写 hashCode 导致误判
- 实现自定义弱引用缓存:用 identityHashCode 作 key 可防止内容相同但实例不同的对象被错误覆盖
- 排查集合异常行为:发现两个“看起来一样”的对象在 HashSet 中重复出现?检查它们的 identityHashCode 是否不同,就能确认是否真为不同实例
注意 null 和基本类型包装类的特殊情况
System.identityHashCode(null) 明确返回 0,不会报错;而 null.hashCode() 直接崩溃。另外,像 Integer、Boolean 这些小范围的包装类(如 -128 到 127)在自动装箱时可能复用缓存对象,导致 identityHashCode 相同——这不是 bug,而是 JVM 的对象池优化行为。
- 不要对 Integer.valueOf(100) 和 new Integer(100) 的 identityHashCode 做相等假设,它们很可能不同
- 浮点数包装类(如 Float)不共享缓存,所以 Float.valueOf(1.0f) 每次都生成新对象,identityHashCode 也不同

















