通常声称Object.hashCode()的实现(所有对象的默认实现)提供了对象的内存地址。该声明通常附加在Object.to String()产生的特殊输出的解释上。

有关示例,请参见here

对于我所知道的任何JVM / JRE,肯定是而不是。尤其重要的是,现在地址通常为64位长。而且,垃圾收集器还会重定位对象,因此地址也会更改。我见过声称它可以是对象的初始内存地址。但是由于许多对象将具有相似的地址,因此对于哈希码而言,这是一个糟糕的选择。

是否存在或曾经存在过任何广泛使用的JVM / JRE,因此它是对象的(初始)内存地址。

我知道Object类的JavaDoc建议实现的hashCode可能是内存地址。但是我怀疑这是一个过时的声明,从未更新过。

实际上,当前的Oracle JVM并不使用内存地址(但可以配置为使用该地址):

https://stackoverflow.com/a/16105878/545127

hashCode是内存地址的想法是历史的产物:

https://stackoverflow.com/a/13860488/545127

我的问题是,广泛使用的JVM的是否(和哪个)使用内存地址作为其(默认)实现。

最佳答案

由于对象的默认哈希码不需要唯一,因此无需返回整个地址。一个实现可以从地址中获取一组位,例如64位系统上的3至35位,或高32位与低32位之间的XOR,或者仅是低32位。

但是由于[由于垃圾回收],那么许多对象将具有相似的地址,因此对于哈希码而言,这是一个糟糕的选择。

数值上彼此接近的哈希码是可以的。即使使用少量相同的哈希码也不会造成问题,因为使用相等性来解决任何联系。通常会限制使用默认哈希代码实现的情况,因为在基于哈希的容器中用作键的对象应该提供hashCode方法的“良好”实现。

Oracle表示,其JVM的默认实现使用该对象的内部地址(无论这意味着什么)来计算其hashCode。但是,不需要其他JVM实现来执行相同的操作:

这是一个quote from Oracle's documentation:

在合理可行的范围内,由hashCode类定义的Object方法确实为不同的对象返回不同的整数。 (通常通过将对象的内部地址转换为整数来实现,但是Java™编程语言不需要此实现技术。)

您可以找到here算法的实际实现。搜索get_next_hash函数以获取详细信息。似乎基于地址的哈希计算是通过简单的转换完成的:

value = intptr_t(obj) ;

07-24 09:49
查看更多