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

标签 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 使用内存地址作为其(默认)实现。

最佳答案

由于对象的默认哈希码不需要是唯一的,因此不需要返回整个地址。实现可以从地址中获取一组位 - 例如,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 class Object 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/

相关文章:

Java swing 布局和/或标签不按顺序

c - 动态库实际上在内存中的什么位置?

c - 通过内联汇编锁定内存操作

java - 在继承层次结构中实现健壮的 equals() 和 hashCode() 方法的正确方法是什么?

java - java中的对象身份哈希码

java - 自动并行化

Java TrayIcon.displayMessage() 在 Windows XP 上不起作用

java - 如何在Java中正确实现MVC模式?

使用App时Java内存使用量增加,但不使用时不减少

java - 如何在hashmap中通过hashcode对随机值进行排序