请问,hashCode 和对象的内存地址有什么关系?我懵了!

本文解析了Java中System.out.println(new Object()).@符号后值的含义,是hashcode的十六进制形式,并探讨了hashCode的生成机制,包括HotSpot VM中的计算方法。作者指出hashCode并非固定内存地址,而是由对象内部状态经过特定算法计算得出。
摘要由CSDN通过智能技术生成

一道小问题,你能答上来吗?

先看一个最简单的打印

System.out.println(new Object());

会输出该类的全限定类名和一串字符串:

java.lang.Object@6659c656

那么问题来了:

@符号后面的是什么?是 hashcode 还是对象的内存地址?还是其他的什么值?

其实 @后面的只是对象的 hashcode 值,16进制展示的 hashcode 而已,来验证一下:

Object o = new Object();
int hashcode = o.hashCode();
// toString
System.out.println(o);
// hashcode 十六进制
System.out.println(Integer.toHexString(hashcode));
// hashcode
System.out.println(hashcode);
// 这个方法,也是获取对象的 hashcode;不过和 Object.hashcode 不同的是,该方法会无视重写的hashcode
System.out.println(System.identityHashCode(o));

输出结果:

java.lang.Object@6659c656
6659c656
1717159510
1717159510

那对象的 hashcode 到底是怎么生成的呢?真的就是内存地址吗?

注:本文内容基于 JAVA 8 HotSpot

0905cc659349a76120ae2b7a08305d24.png

47942aab8f93e66a7884ff43a7ebd12f.png

8cf05659f16e725351fd5e849e5257f3.png

8f741c3c878f46a9cf07d04a2d054635.png

d8de8f8f30071e3cf8ade39e9fa2d3cf.png

bcafada2f0ca88fb1eafedf4a6f823a1.png

a89e9f04ba657e099c964bb9e2c6bcef.png

Self->_hashStateZ = Self->_hashStateW ;
     unsigned v = Self->_hashStateW ;
     v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
     Self->_hashStateW = v ;
     value = v ;
  }

这里是通过当前状态值进行异或(XOR)运算得到的一个 hash 值,相比前面的自增算法和随机算法来说效率更高,但重复率应该也会相对增高,不过 hashCode 重复又有什么关系呢……

本来 jvm 就不保证这个值一定不重复,像 HashMap 里的链地址法就是解决 hash 冲突用的

结论

hashCode 可以是内存地址,也可以不是内存地址,甚至可以是 1 这个常数或者自增数!想用什么算法,它都可以!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值