Java 为什么hashCode()在所有连续执行中为对象返回相同的值?

Java 为什么hashCode()在所有连续执行中为对象返回相同的值?,java,equality,Java,Equality,我正在尝试一些java中关于对象相等的代码。正如我在某处读到的 hashCode()是通过应用哈希函数生成的数字。每个对象的哈希函数可以不同,但也可以相同。在对象级别,它返回对象的内存地址 现在,我有一个示例程序,我连续运行了10次。每次运行该程序时,我都会得到与哈希代码相同的值 for (int i=0; i < 10; i++) { System.out.println("i: " + i + ", hashCode: " + new Object().hashCode());

我正在尝试一些java中关于对象相等的代码。正如我在某处读到的

hashCode()
是通过应用哈希函数生成的数字。每个对象的哈希函数可以不同,但也可以相同。在对象级别,它返回对象的内存地址

现在,我有一个示例程序,我连续运行了10次。每次运行该程序时,我都会得到与哈希代码相同的值

for (int i=0; i < 10; i++) {
    System.out.println("i: " + i + ", hashCode: " + new Object().hashCode());
}
如果
hashCode()
函数返回对象的内存位置,那么java(JVM)如何在连续运行中将对象存储在相同的内存地址

你能给我一些见解和你对这个问题的看法吗

我正在运行的测试此行为的程序如下所示:

public class EqualityIndex {

    private int index;

    public EqualityIndex(int initialIndex) {
       this.index = initialIndex;
    }

    public static void main(String[] args) {
        EqualityIndex ei = new EqualityIndex(2);
        System.out.println(ei.hashCode());
    }

}

每次我运行这个程序时,返回的散列码值都是
4072869

创建了哪种类型的对象?它是一种特殊类型的对象,如字符串(例如)。如果它是一种特定类型,则该类已经可以重写hashCode()方法并将其返回给您。在这种情况下,您收到的不再是内存地址

以及您接收到的值,是否确定它是内存地址


因此,请发布更多代码以了解更多详细信息。

好吧,对象很可能最终位于虚拟内存中的同一位置。这一点并不矛盾。底线是你无论如何都不应该在意如果实现hashCode以返回与内部存储地址相关的内容(根本不能保证!),那么您对该信息也没有任何用处

java(JVM)如何在连续运行中将对象存储在相同的内存地址


为什么不呢?非内核程序从不使用绝对内存地址,它们使用虚拟内存,每个进程都有自己的地址空间。因此,毫不奇怪,确定性程序在每次运行时都会将内容放在相同的位置。

哈希代码可以并且可能被您使用的类覆盖,声明它是“。。。通常通过将对象的内部地址转换为整数来实现…,因此实际实现可能取决于系统。还要注意JavaDoc中的第三点,即不相等的两个对象不需要返回不同的哈希代码。

如果两个对象相等,则它们必须具有相同的哈希代码。所以,只要不创建普通的
对象
实例,每次创建具有相同值的对象时,都会得到相同的哈希代码

for (int i=0; i < 10; i++) {
    System.out.println("i: " + i + ", hashCode: " + new Object().hashCode());
}
正如我在某个地方读到的:“……在对象级别,它返回对象的内存地址。”

这种说法是不正确的,或者充其量只是过于简单化

该语句引用的是
Object.hashCode()
的默认实现,它返回的值与
System.identityHashcode(Object)
相同

Object.hashCode()
的Javadoc说明:

只要是合理可行的,类对象定义的hashCode方法确实会为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要这种实现技术。)

这是:

在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须始终返回相同的整数

事实上,当第一次为对象调用方法时,标识hashcode值通常基于对象的机器地址。该值存储在对象标题中的隐藏字段中。这允许在后续调用中返回相同的哈希代码。。。即使GC同时重新定位了对象

请注意,如果标识hashcode值在对象的生命周期内发生更改,则它将违反
hashcode()
的约定,并且作为hashcode是无用的。

函数应在同一执行中为同一对象返回相同的值。对于不同的执行,不必返回相同的值。请参阅从
对象
类中提取的以下注释

hashCode的总合同为:

在执行过程中多次在同一对象上调用 Java应用程序的执行,hashCode方法 必须始终返回相同的整数,但不提供任何信息 用于修改对象上的相等比较。 此整数不需要从一次执行 应用程序到同一应用程序的另一个执行。

我已经执行了你的代码好几次了。 这是我的结果

1935465023

1425840452

1935465023

1935465023

1935465023

1925529038

1935465023

1935465023


同一数字重复多次。但这并不意味着它们总是一样的。让我们假设,JVM的一个特定实现正在内存中寻找第一个空闲插槽。然后,如果您不运行任何其他应用程序,则在同一插槽中分配对象的可能性很高。

您的对象是什么?显示一些代码。您确定您的值是内存地址吗?你能发布它吗?Java的默认值
.hashCode()
实际上更像是一个增量内存标识符,而不是地址。因此,当前提条件相同时,结果也是一样的。“在对象级别上,它返回对象的内存地址。”该语句大约过期12年。它并不总是正确的。这取决于你谈论的班级。这是一个很好的惯例,总是覆盖等于