new Integer(1)与int类型1的System.identityHashCode差异及对象疑问
问题解答:c引用的"1"对象是否与a、b的不同?
没错,你观察得很准确——c引用的Integer对象确实和a、b对应的那个“1”对象不是同一个,下面结合你的代码和Java的特性来详细解释:
先回顾你的测试代码
首先是变量赋值部分:
jshell> int a = 1; a ==> 1 jshell> int b = 1; b ==> 1 jshell> var c = new Integer(1); c ==> 1
然后用System.identityHashCode检查哈希码的结果:
jshell> System.out.println(System.identityHashCode(1)) 1938056729 jshell> System.out.println(System.identityHashCode(a)) 1938056729 jshell> System.out.println(System.identityHashCode(b)) 1938056729 jshell> System.out.println(System.identityHashCode(c)) 343965883
为什么哈希码会有差异?
这里的核心是Java的Integer常量池和自动装箱机制,以及System.identityHashCode的作用:
System.identityHashCode(Object x)返回的是对象内存地址对应的哈希码(可以简单理解为“对象唯一标识”,除非哈希碰撞,不同对象会返回不同值)。- 对于
a和b:它们是基本类型int,当你调用System.identityHashCode(a)时,Java会自动把int值装箱成Integer对象。而Java为了优化性能,会对-128到127之间的整数进行缓存,所以每次装箱值为1的int时,都会复用常量池里的同一个Integer实例,因此它们的标识哈希码完全相同。 - 对于
c:new Integer(1)是显式创建了一个全新的Integer对象,这个操作不会去复用常量池里的缓存实例,所以它和自动装箱出来的Integer对象是两个完全独立的内存实例,自然标识哈希码就不一样了。
额外验证:用引用比较确认
你可以在jshell里再跑一段代码验证:
jshell> (Integer)a == c $5 ==> false
这里把a手动装箱成Integer后,用==比较引用(引用类型的==比较的是内存地址),结果为false,直接证明了两个对象不是同一个。
内容的提问来源于stack exchange,提问作者Wizard
相关产品推荐
相关产品推荐

