Object.toString或Object.hashCode是否给出了对象的内存地址

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

请看这里的例子。

对于我所知道的任何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实现不需要执行相同的操作:

以下是Oracle文档的引用 :

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

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

 value = intptr_t(obj) ;