Java中未初始化数组元素的哈希码何时确定?
关于int数组元素identityHashCode的时机与机制解析
首先要明确几个核心事实:
System.identityHashCode()仅对对象生效,传入基本类型(比如int)时会自动触发装箱操作,把基本类型转为对应的包装类对象(这里是Integer)。你看到的所谓"数组元素的哈希码",本质是装箱后Integer对象的identityHashCode,和基本类型int本身无关。int数组创建时,只会给每个元素分配内存并设为默认值0,这一步完全是基本类型的内存操作,不会创建任何Integer对象,自然也不存在所谓的"哈希码"。
哈希码的确定时机
只有当你第一次调用System.identityHashCode(arr[0])这类代码时,JVM才会执行以下操作:
- 把
arr[0]的int值0装箱为Integer对象,调用Integer.valueOf(0)。 - 如果是JVM启动后首次处理
0的装箱,会创建(或从缓存中取出)对应的Integer实例,此时该对象的identityHashCode就确定了(基于JVM的对象内存地址或其他内部机制,创建时生成)。
为何哈希码和访问顺序相关
你观察到的"按访问顺序生成哈希码",本质是JVM中对象创建顺序的体现:
- 在测试3中,你先调用
System.identityHashCode(arr2[0]),此时JVM首先创建(或取出)Integer.valueOf(0)的实例,这个对象的identityHashCode是当前JVM分配的第一个可用哈希值;随后创建的数组对象arr2会拿到下一个哈希值。 - 在测试4中,你先调用
System.identityHashCode(arr2),数组对象先被创建,拿到第一个哈希值;随后触发装箱的Integer.valueOf(0)实例拿到下一个哈希值。 - 而同一个数组里的两个
0装箱后会返回同一个Integer实例(因为Integer对-128~127的数值有缓存机制),所以它们的identityHashCode始终相同。
总结
你看到的"首次访问才确定哈希码"是个误解:哈希码是装箱后Integer对象的属性,在对象创建时就确定了;而数组元素本身是基本类型,不存在哈希码,只有当你首次访问并触发装箱时,才会创建对应的Integer对象,进而生成哈希码。
内容的提问来源于stack exchange,提问作者ChoCoc
相关产品推荐
相关产品推荐

