Object.toString或Object.hashCode是否提供对象的内存地址

时间:2016-03-26 14:43:15

标签: java memory hashcode

通常声称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是否使用内存地址作为其(默认)实现。

1 个答案:

答案 0 :(得分:2)

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

  

但是由于许多对象会有类似的地址[由于垃圾收集],因此对于哈希码来说这将是一个糟糕的选择。

在数值上彼此接近的哈希码是可以的。即使少量相同的哈希码也不会产生问题,因为使用相等来解决任何关系。使用默认哈希码实现的情况通常是有限的,因为在基于哈希的容器中用作键的对象应该提供" good" hashCode方法的实现。

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

这是quote from Oracle's documentation

  

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

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

value = intptr_t(obj) ;
相关问题