![](/img/trans.png)
[英]default implementation of hashcode returns different values for objects constructed the same way
[英]Default hashCode() implementation for Java Objects
我試圖理解Java的Object的hashCode(),並看到Java Object的hashCode()方法的以下代碼:
package java.lang;
public class Object {
// Some more code
public native int hashCode();
// Some other code
}
package com.example.entity;
public class FirstClass {
private int id;
private String name;
// getters and setters
}
所以,這個類即: FirstClass
將隱式擴展Object
類。
package com.example.app.main;
import com.example.entity.FirstClass;
public class MainApp {
public static void main(String[] args) {
FirstClass fs = new FirstClass();
fs.setId(1);
fs.setName("TEST");
System.out.println("The hasCode for object fs is " + fs.hashCode());
}
}
由於FirstClass
隱式擴展Object
類,因此它將具有Object
類的hashCode()
方法。
我在FirstClass
對象上調用了hashCode()
,因為我沒有覆蓋hashCode()
,所以理論上它應該調用Object
類的hashCode()
。
由於Object類沒有任何實現,如何計算任何對象的哈希碼?
在我的例子中,當我運行程序時,它返回的哈希碼是366712642。
任何人都可以幫我理解這個嗎?
雖然這里有一些答案表明默認實現是基於“內存”的,但這是完全錯誤的。 現在很多年情況並非如此。
在java-8下,你可以這樣做:
java -XX:+PrintFlagsFinal | grep hashCode
獲取使用的確切算法(默認值為5
)。
0 == Lehmer random number generator,
1 == "somehow" based on memory address
2 == always 1
3 == increment counter
4 == memory based again ("somehow")
5 == read below
默認情況下( 5
),它使用的是Marsaglia XOR-Shift算法,它與內存無關。
如果您這樣做,這不是很難證明:
System.out.println(new Object().hashCode());
多次,在一個新的VM中 - 你將獲得相同的值,因此Marsaglia XOR-Shift以種子開始(總是相同,除非其他一些代碼不會改變它)並從中開始工作。
但即使你切換到一些基於內存的hashCode,而Objects可能會四處移動(垃圾收集器調用),你如何確保在 GC移動這個對象后采取相同的hashCode? 提示:indentityHashCode和Object標頭。
你弄錯了:
public native int hashCode();
並不意味着沒有實施。 它只是意味着該方法是在JVM的原生又名C / C ++部分中實現的。 這意味着您無法找到該方法的Java源代碼。 但是,只要在某些Object上調用hashCode()
,JVM中的某些代碼就會被調用。
正如另一個答案所解釋的那樣:“默認”實現使用了底層對象的“內存”地址。 事情是:使用java意味着,沒有“內存地址”的知識。 請記住:JVM是用C / C ++編寫的 - 真正的內存管理發生在JVM的這些本機部分。
換句話說:您無法編寫告訴您有關對象的“本機內存地址”的Java代碼。
但正如Eugene的另一個答案所表明的那樣:關於“記憶位置”的哈希是過去的事情。
對象類中Hashcode的默認實現是對象的十六進制內存地址。 JVM調用此實現。
一些有用的鏈接是:
https://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.