簡體   English   中英

Java對象的默認hashCode()實現

[英]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

}

現在,我們知道如果我們創建一個類,它會隱式擴展Object類,為此,我編寫了一個示例示例:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM