我试图理解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
}
因此,该类即: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()
方法。
我调用了hashCode()
on FirstClass
对象,但由于尚未覆盖on
hashCode()
,因此从理论上讲它应该调用Object
class的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中的一个测试类
问题内容: 我正在尝试找出是否有一种方法可以使用默认参数的对象分解,而不必担心对象被部分定义。考虑以下: 例如,当我用调用时,我在控制台中看到的是我真正想要的时间。有没有一种方法可以实现而无需手动检查对象的所有属性? 问题答案: 是。您也可以在解构中使用“默认值”: 这不限于函数参数,而是适用于每个解构表达式。