Him*_*shu 40 java object hashcode
如何做Object.hashCode()和System.identityHashCode()工作在后端?是否identityHashCode()返回对象的引用?是否hashCode()取决于?对象?==运算符如何在后端工作.
hashCode()和之间有什么区别identityHashCode()?
Ste*_*n C 32
Object.hashCode()和System.identityHashCode()如何在后端工作?
假设它没有被覆盖,该Object.hashCode()方法只是调用System.identityHashCode(this).
确切的行为System.identityHashCode(Object)取决于JVM实现.(最近的Hotspot JVM的实际实现相当聪明,但我离题了.)
是否
identityHashCode()返回对象的引用?
不.它返回一个int,并且int不能保持参考.(咄!)
返回的整数identityHashCode可能与(a)对象的机器地址有关,也可能不是1.identityHashCode() 保证返回的值不会在对象的生命周期内更改.这意味着GC重新定位一个对象(在identityHashCode()调用之后),然后它不能使用新的对象地址作为标识哈希码.
hashCode()是否依赖于
?对象? ==操作符如何在后端工作.
这没有意义.Java中没有? ==或?==运算符.
hashCode()和identityHashCode()有什么区别?
以上部分解释了这一点.其他差异包括:
该hashcode()方法是非最终实例方法,应该在被覆盖的任何类中equals(Object)重写.相比之下,identityHashCode(Object)是一种static方法,因此不能被覆盖.
该identityHashCode(Object)方法为您提供了一个对象的标识符,该标识符可以(理论上)用于除散列和散列表之外的其他内容.(不幸的是,它不是一个独特的标识符,但被保证从不为对象的生命周期变化).
1 - 对于当前生成的JVM,它根本与内存地址无关.请参阅@ bestsss的答案.
bes*_*sss 20
identityHashCode()的工作方式与此类似(截至目前,它没有任何关于地址的信息,特别是因为地址长度为64位,所以对齐,所以61)
检查是否已生成一个,如果是,则返回它.您可以假设对象标题中有一个位置int;
否则:生成一个随机数(iirc twister Marsaglia shift-xor算法),每个本机线程都有自己的种子,所以没有共享信息.CAS identityHashCode对象头中的字段用新生成的数字更新.如果CAS成功返回值,如果不是 - 该字段已包含已生成的值identityHashCode.
您可以看到有关覆盖哈希码的其余回复.
底线:如果javadoc仍然陈述有关地址和identityHashCode的任何内容,则有人需要更新它.
tem*_*def 11
这几乎是特定于实现的.你得到的唯一保证是
尽管合理可行,但是
hashCode由class定义的方法Object确实为不同的对象返回不同的整数.(这通常通过将对象的内部地址转换为整数来实现,但Java TM编程语言不需要此实现技术.)
(来自Java 1.6 JavaDoc)
理论上,这意味着这些值可以任意确定,甚至可以为每个对象为零.在实践中,它可能是从对象的地址派生的东西.当然,你必须要小心这一点.如果JVM在垃圾收集期间认为它是个好主意,它可以重新定位对象,因此它不会"只是"内存地址.它可以从全局计数器,或原始对象的位置的散列,或从随机数生成器等中提取.
上面已经回答了很多,补充几点。
当我们说obj.hashCode()考虑 obj 的内容时,另一方面,System.identityHashCode(obj)不考虑内容,因此identityHashCode对于两个不同的String,int(具有相同值)将不同但Hashcode将相同。
如果String要获取identityHashCode字符串池起着重要作用,例如
Object s1 = "abcd";
Object s2 = new String("abcd");
Object s3 = "abcd";
System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());
//output:
identityHashCode : 2018699554 HashCode : 2987074
identityHashCode : 1311053135 HashCode : 2987074
identityHashCode : 2018699554 HashCode : 2987074
Run Code Online (Sandbox Code Playgroud)
这里s1并s3指向相同的引用,因此identityHashCodefors1 and s3总是相同的并且s2会有所不同。
同样int,IntegerCache在获得identityHashCode
Object s1 = 5;
Object s2 = new Integer(5);
Object s3 = 5;
System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());
//Output
identityHashCode : 2018699554 HashCode : 5
identityHashCode : 1311053135 HashCode : 5
identityHashCode : 2018699554 HashCode : 5
Run Code Online (Sandbox Code Playgroud)
身份哈希码
公共静态 int 身份HashCode(对象x)
为给定对象返回与默认方法 hashCode() 返回的哈希码相同的哈希码,无论给定对象的类是否覆盖 hashCode()。空引用的哈希码为零。
请参阅 [ Java 文档]
因此,如果有人在其类中重写了方法,但仍然想要由Object返回的hashCode()默认值,则使用hashCode() hashCode()System.identityHashCode()
因此,只要您不在类中重写它,hashCode()内部调用就会被调用,如果您重写 hashCode() ,它将调用您的实现。System.identityHashCode()
| 归档时间: |
|
| 查看次数: |
16591 次 |
| 最近记录: |