当前位置: 首页 > 面试题库 >

Java对象的默认hashCode()实现

顾昌翰
2023-03-14
问题内容

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

因此,该类即: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标头。



 类似资料:
  • 问题内容: 如果没有覆盖该方法,默​​认的实现是什么? 问题答案: 然后,此类从其祖先之一继承。如果它们都不覆盖它,则使用Object.hashCode。 从文档: 在合理可行的范围内,由Object类定义的hashCode方法确实为不同的对象返回不同的整数。(通常通过将对象的内部地址转换为整数来实现,但是JavaTM编程语言不需要此实现技术。) 因此默认实现是特定于JVM的

  • 下面是记录和类的代码示例 执行后,上述代码的输出为: 有谁能帮我了解一下record的默认equals和hashcode实现的行为与上面有什么不同吗? 如果equals和hashcode实现中有更改,则进行记录。那么请帮助我理解这个变化的确切目的是什么,以及在哪些情况下使用它会更有帮助。 提前感谢!!

  • 问题内容: 我发现Java 的根类方法没有实现: 如果我有一个and an ,如何不使用就知道the 和value ?只需执行即可。 我尝试了两个对象,但令我大吃惊的是值是相同的:它们都是1。 问题答案: 是一种方法,意味着系统库在内部被调用。有关更多详细信息,请参见Java本机接口。

  • 问题内容: 我了解hashCode的思想以及为什么需要它。但是我对如何为通用对象计算hashCode感到困惑。所以这是我的问题。如果我有一个String,我可能会使用以下函数来计算hashCode, 但是说我有以下目的, 我的IDE为此生成了一个自动的hashCode函数, 我的问题是,由于键和值是通用的,该怎么办?这种方法如何运作? 问题答案: 和是参数化类型的的对象。 这样,将在实际类型上被调

  • 我在airport.java中有一个枚举类 和Test.java中的一个测试类

  • 问题内容: 我正在尝试找出是否有一种方法可以使用默认参数的对象分解,而不必担心对象被部分定义。考虑以下: 例如,当我用调用时,我在控制台中看到的是我真正想要的时间。有没有一种方法可以实现而无需手动检查对象的所有属性? 问题答案: 是。您也可以在解构中使用“默认值”: 这不限于函数参数,而是适用于每个解构表达式。