java - Java 对象的默认 hashCode() 实现

标签 java java-8 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
}

因此,这个类即: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());

在新的虚拟机中始终多次 - 您将获得相同的值,因此 Marsaglia XOR-Shift 从种子开始(始终相同,除非某些其他代码不会改变它)并从此开始工作。

但是,即使您切换到一些基于内存的 hashCode,并且对象可能会四处移动(垃圾收集器调用),您如何确保在 GC 移动该对象之后采用相同的 hashCode ?提示:indentityHashCode 和 Object header 。

关于java - Java 对象的默认 hashCode() 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49172698/

相关文章:

java - 如何在 GWT 中有选择地打开 JSNI 部分?

java - 为什么 .forEach(val -> list.add()) 编译而 .forEach(val -> true) 不编译?

java - 在 Java 中对数组实例调用 hashCode()

java - Set.equals 的奇怪行为

java - stringtokenizer 返回错误的标记

java - 射线平方交集

java-8 - Java 8 Stream anyMatch() 遍历整个流

java - 如何在 Flowable.generate 中使 Files.lines AutoCloseable

java - 为什么这是 `hashCode()` 的一个很好的实现

java - 如何为 swagger 2.8.0 做友好的基本 url