java hashCode() 和 identityHashCode() 在后端如何工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4930781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do hashCode() and identityHashCode() work at the back end?
提问by Himanshu
How do Object.hashCode()
and System.identityHashCode()
work at the back end? Does identityHashCode()
return the reference of the object? Does hashCode()
depend on the ? of the object ? == operator how to work in back end.
如何做Object.hashCode()
和System.identityHashCode()
工作在后端?是否identityHashCode()
返回对象的引用?不hashCode()
取决于?的对象?== 运算符如何在后端工作。
What is the difference between hashCode()
and identityHashCode()
?
hashCode()
和 和有什么不一样identityHashCode()
?
回答by Stephen C
How do Object.hashCode() and System.identityHashCode() work at the back end?
Object.hashCode() 和 System.identityHashCode() 在后端是如何工作的?
Assuming that it hasn't been overridden, the Object.hashCode()
method simply calls System.identityHashCode(this)
.
假设它没有被覆盖,该Object.hashCode()
方法只是调用System.identityHashCode(this)
.
The exact behavior of System.identityHashCode(Object)
depends on the JVM implementation. (The actual implementation on recent Hotspot JVMs is rather clever, but I digress.)
的确切行为System.identityHashCode(Object)
取决于 JVM 实现。(最近 Hotspot JVM 的实际实现相当聪明,但我离题了。)
Does
identityHashCode()
return the reference of the object?
是否
identityHashCode()
返回对象的引用?
No. It returns an int
, and an int
cannot hold a reference.
不。它返回一个int
,并且一个int
不能保存引用。
That integer returned by identityHashCode
may be related to the (a) machine address for the object, or it may not be1. The value returned by identityHashCode()
is guaranteed not to changefor the lifetime of the object. This means that if the GC relocates an object (after an identityHashCode()
call) then it cannot use the new object address as the identity hashcode.
返回的整数identityHashCode
可能与对象的 (a) 机器地址有关,也可能不是1。返回的值identityHashCode()
保证在对象的生命周期内不会改变。这意味着如果 GC 重新定位一个对象(在identityHashCode()
调用之后),那么它不能使用新的对象地址作为身份哈希码。
Does hashCode() depend on the
?
of the object? ==
operator how to work in back end.
hashCode() 是否取决于
?
对象? ==
运算符的后端如何工作。
This doesn't make sense. There is no ? ==
or ?==
operator in Java.
这没有意义。Java 中没有? ==
or?==
运算符。
What is the difference between hashCode() and identityHashCode()?
hashCode() 和 identityHashCode() 有什么区别?
This is partly explained above. Other differences include:
上面已经部分解释了这一点。其他差异包括:
The
hashcode()
method is a non-final instance method, and should be overridden in any class where theequals(Object)
is overridden. By contrast,identityHashCode(Object)
is astatic
method and therefore cannot be overridden.The
identityHashCode(Object)
method gives you a identifier for an object which can (in theory) be used for other things than hashing and hash tables. (Unfortunately, it is not a uniqueidentifier, but it isguaranteed to never change for the lifetime of the object.)
该
hashcode()
方法是一个非最终实例方法,应该在任何被覆盖的类中equals(Object)
被覆盖。相比之下,identityHashCode(Object)
是一种static
方法,因此不能被覆盖。该
identityHashCode(Object)
方法为您提供了一个对象的标识符,该标识符(理论上)可以用于除散列和散列表之外的其他事情。(不幸的是,它不是一个独特的标识符,但被保证为对象的生命周期永远不会改变。)
1 - For current generation JVMs, it is not related to the memory address at all. See @bestsss's answer.
1 - 对于当前一代 JVM,它与内存地址完全无关。请参阅@bestsss 的回答。
回答by bestsss
identityHashCode() works like that (and as of now it has nothing do to w/ the address, esp. since the addresses are 64bits long, ok aligned, so 61)
identityHashCode() 就是这样工作的(到目前为止它与地址无关,尤其是因为地址是 64 位长,可以对齐,所以 61)
Checks if the there is already generated one, if so returns it. You can assume there is a place in the object header for that int
;
检查是否已经生成了一个,如果是则返回它。您可以假设对象标题中有一个位置int
;
otherwise: generates a random number (iirc twisterMarsaglia shift-xoralgorithm), every native thread has its own seed, so no shared info.
CAS the identityHashCode
field in the object header to update w/ the newly generated number. if CAS success returns the value, if not - the field already contains a generated identityHashCode
.
否则:生成一个随机数(iirc twiner Marsaglia shift-xoralgorithm),每个本地线程都有自己的种子,所以没有共享信息。CASidentityHashCode
对象标头中的字段以更新新生成的数字。如果 CAS 成功返回值,否则 - 该字段已包含生成的identityHashCode
.
you can see the rest of the replies about overriding hashcode.
你可以看到其他关于覆盖哈希码的回复。
bottom line: if the javadoc still states anything about addresses and identityHashCode, someone needs to update it.
底线:如果 javadoc 仍然说明了有关地址和 identityHashCode 的任何内容,则需要有人对其进行更新。
回答by templatetypedef
This is pretty much implementation specific. The only guarantee you get is
这几乎是特定于实现的。你得到的唯一保证是
As much as is reasonably practical, the
hashCode
method defined by classObject
does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTMprogramming language.)
尽管合理可行,
hashCode
类定义的方法Object
确实为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的,但是 Java TM编程语言不需要这种实现技术。)
(From the Java 1.6 JavaDoc)
(来自 Java 1.6 JavaDoc)
In theory, this means that the values could be determined arbitrarily and could even be zero for every object. In practice, it's probably something derived from the address of the object. Of course, you have to be careful about this. The JVM can relocate objects if it thinks it's a good idea during a garbage collection, so it's not going to be "just" the memory address. It could be drawn from a global counter, or a hash of the original object's location, or from a random number generator, etc.
从理论上讲,这意味着可以任意确定这些值,甚至对于每个对象都可以为零。在实践中,它可能是从对象的地址派生的。当然,你必须小心这一点。如果 JVM 认为在垃圾收集期间这是一个好主意,它可以重新定位对象,因此它不会“只是”内存地址。它可以从全局计数器、原始对象位置的散列或随机数生成器等中提取。
回答by Vishrant
identityHashCode
public static int identityHashCode(Object x)
Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class overrides hashCode(). The hash code for the null reference is zero.
身份哈希码
public static int identityHashCode(Object x)
为给定对象返回与默认方法 hashCode() 返回相同的哈希码,无论给定对象的类是否覆盖 hashCode()。空引用的哈希码为零。
See [Java docs]
请参阅 [ Java 文档]
So if someone has overridden hashCode()
method in its class but still want the default hashCode()
value which would have been returned by ObjecthashCode()
then use System.identityHashCode()
因此,如果有人hashCode()
在其类中重写了方法,但仍希望使用ObjecthashCode()
返回的默认值,则使用hashCode()
System.identityHashCode()
So, hashCode()
internally calls System.identityHashCode()
as long as you are not overriding it in you class, if you override hashCode() it will call your implementation.
因此,只要您没有在类中覆盖它,hashCode()
内部调用System.identityHashCode()
就会调用,如果覆盖 hashCode() 它将调用您的实现。
回答by Hitesh Ghuge
Lots of answers given above, just need to add some points.
上面给出了很多答案,只需要补充一些要点。
When we say obj.hashCode()
the content of the obj is considered, on the other hand
in System.identityHashCode(obj)
the content are not taken in consideration, thus identityHashCode
for two different String
, int
(with same value) will be the different but Hashcode
will be the same.
当我们说obj.hashCode()
obj 的内容被考虑时,另一方面在System.identityHashCode(obj)
内容中没有考虑,因此identityHashCode
对于两个不同的String
,int
(具有相同的值)将不同但Hashcode
会相同。
In case of String
to get identityHashCode
string pool plays important role, example
在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
here s1
and s3
pointing same ref therefore identityHashCode
for s1 and s3
is always same and s2
will be different.
heres1
和s3
指向相同的 ref 因此identityHashCode
fors1 and s3
总是相同的,并且s2
会有所不同。
Same for int
also, IntegerCache
plays the important role to get the identityHashCode
同样为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