通常声称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 位之间的异或,或者只是低 32 位。
But as many objects would then have similar addresses [due to garbage collection], that would be a poor choice for a hash code.
在数值上彼此接近的哈希码是可以的。即使是少量相同的哈希码也不会产生问题,因为相等性用于解决任何关系。使用默认哈希代码实现的情况通常是有限的,因为在基于哈希的容器中用作键的对象应该提供 hashCode
方法的“良好”实现。
Oracle 说他们的 JVM 的默认实现使用对象的内部地址,不管那是什么意思,来计算它的 hashCode
。然而,其他 JVM 实现不需要做同样的事情:
这是一个quote from Oracle's documentation :
As much as is reasonably practical, the
hashCode
method defined by classObject
does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java™ programming language.)
你可以找到算法的实际实现here .搜索 get_next_hash
函数了解详情。看起来基于地址计算哈希是通过简单的转换完成的:
value = intptr_t(obj) ;
关于java - Object.toString 或 Object.hashCode 是否给出了对象的内存地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36236615/