Java对象的默认hashCode()实现

我试图理解Java对象的hashCode(),并看到Java对象的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

}

因此,该类即:FirstClassObject隐式扩展该类。

主班:

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()方法。

我调用了hashCode()on FirstClass对象,但由于尚未覆盖on

hashCode(),因此从理论上讲它应该调用Objectclass的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,并且对象可能会四处移动(垃圾回收器调用),如何确保 GC移动了该对象 后仍

采用相同的hashCode ?提示:indentityHashCode和Object标头。

以上是 Java对象的默认hashCode()实现 的全部内容, 来源链接: utcz.com/qa/431385.html

回到顶部