Java的System.identityHashCode()
方法
返回给定对象的哈希码,与该对象所属类是否重写hashCode()方法无关。
该哈希码基于对象标识,因此对于相同的对象,无论在调用identityHashCode()
之间对象是否被修改,它始终是相同的。
除此之外,在一些Java运行时中,任何两个活动对象之间都不会发生哈希冲突:(这是Oracle在下面的源代码中的一种不准确的陈述,正如Jai的回答所示,以及另一个错误报告所指出的那样——这基本上使我的原始问题无效...)
[...] 垃圾对象可以被轻松回收并且地址空间可以被重新使用。冲突是由于地址空间的重用而导致的。如果原始对象保持活动状态(未被GC),则不会遇到此问题。
在 .Net 中,有 RuntimeHelpers.GetHashCode()
,它满足第一个条件,但不满足第二个条件:
请注意,GetHashCode 对于相等的对象引用始终返回相同的哈希码。然而,反之并不成立:相等的哈希码并不表示相等的对象引用。特定的哈希码值并不唯一地对应于特定的对象引用;不同的对象引用可以生成相同的哈希码。
那么,在 .Net 中是否有类似于 Java 的 identityHashCode()
的东西呢?
编辑:
有人认为这与 C# 中对象的内存地址 相同,但实际上不是,因为内存地址不能在此处(仅)使用,因为内存管理会移动对象,因此对象的生命周期内地址可能会发生变化。
Object#hashCode()
和System.identifyHashCode()
保证了它返回给定实例的值永远不会改变,但它并没有提到它会为每个对象返回一个唯一的值。事实上,它只返回对象在堆中的末尾32位内存地址 - 这意味着0x 0 FFFF FFFF
和0x 1 FFFF FFFF
都将返回0x FFFF FFFF
。您可以修改错误报告的示例,例如创建一个静态列表来存储obj
以防止GC,但仍然会发生冲突。 - Jai