Object.toString 或 Object.hashCode 是不是曾经给出对象的内存地址
Posted
技术标签:
【中文标题】Object.toString 或 Object.hashCode 是不是曾经给出对象的内存地址【英文标题】:Does Object.toString or Object.hashCode ever give the memory address of the objectObject.toString 或 Object.hashCode 是否曾经给出对象的内存地址 【发布时间】:2016-03-26 14:43:14 【问题描述】:经常声称Object.hashCode()
的实现(所有对象的默认实现)给出了对象的内存地址。这种说法通常附在对 Object.to String() 产生的特殊输出的解释中。
有关示例,请参阅 here。
这对于我所知道的任何 JVM/JRE 来说肯定是不是的。尤其是因为现在地址通常是 64 位长。而且,垃圾收集器会重新定位对象,因此地址会发生变化。我已经看到声称它可以是对象的 initial 内存地址。但由于许多对象将具有相似的地址,这对于哈希码来说是一个糟糕的选择。
是否存在或曾经存在任何广泛使用的 JVM/JRE,它是对象的(初始)内存地址。
我知道Object
类的JavaDoc 表明实现的hashCode
可能是内存地址。但我怀疑这是一个从未更新过的严重过时的声明。
确实,当前的Oracle JVM不使用内存地址(但可以配置为这样做):
https://***.com/a/16105878/545127
hashCode 是内存地址的想法是一个历史产物:
https://***.com/a/13860488/545127
我的问题是任何广泛使用的 JVM 是否(以及哪个)使用内存地址作为其(默认)实现。
【问题讨论】:
在 HotSpot 中可配置:***.com/questions/16105420/… 大概是 Sun JVM 当时的 javadoc 被修改为包含那句话? (您的意思是要问是否有任何 当前 JVM 可以做到这一点?) 另见***.com/questions/13860194/… 【参考方案1】:由于对象的默认哈希码不需要唯一,因此不需要返回整个地址。实现可以从地址中获取一组位 - 例如,64 位系统上的位 3 到 35,或者高 32 位和低 32 位之间的异或,或者只是低 32 位。
但由于许多对象将具有相似的地址 [由于垃圾收集],这对于哈希码来说将是一个糟糕的选择。
数字上彼此接近的哈希码是可以的。即使是少量相同的哈希码也不会产生问题,因为相等用于解决任何关系。使用默认哈希码实现的情况通常是有限的,因为在基于哈希的容器中用作键的对象应该提供hashCode
方法的“好”实现。
Oracle 说他们的 JVM 的默认实现使用对象的内部地址来计算它的hashCode
。但是,其他 JVM 实现不需要这样做:
这是quote from Oracle's documentation:
在合理可行的情况下,
Object
类定义的hashCode
方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但 Java™ 编程语言不需要这种实现技术。)
你可以找到算法here的实际实现。搜索get_next_hash
函数了解详情。看来,基于地址计算哈希是通过简单的转换完成的:
value = intptr_t(obj) ;
【讨论】:
关于内部地址的说法是否真的。我看过(抱歉没有参考)一篇另有说明的文章。 @Raedwald 这是复制粘贴straight from the horse's mouth 低 32 位是一个糟糕的选择,因为对象地址将在字边界上对齐。 @TassosBassoukos:您知道 JVM 的实现不止一种吗?参看。 en.wikipedia.org/wiki/List_of_Java_virtual_machines 但它是唯一的,即没有其他“广泛使用的JVM”吗? (我不知道,我只是想指出,仅仅检查一个 JVM 的源代码可能不足以最终回答 OP 的问题)以上是关于Object.toString 或 Object.hashCode 是不是曾经给出对象的内存地址的主要内容,如果未能解决你的问题,请参考以下文章
Java中Object.toString()返回的字符串的含义
NullPointerException:无法调用“Object.toString()”,因为“javax.swing.JButton.getIcon()”的返回值为 null