【发布时间】:2015-09-08 05:55:04
【问题描述】:
在Java中,Object的hashcode值是根据对象的内容还是根据对象的实例内存地址通过算法生成的?
【问题讨论】:
-
@HarryBlargle,很遗憾,完全不正确的答案在那里得到了高度评价和接受。
标签: java object hashcode gethashcode
在Java中,Object的hashcode值是根据对象的内容还是根据对象的实例内存地址通过算法生成的?
【问题讨论】:
标签: java object hashcode gethashcode
如果你去Java源代码的Object类,它是这样实现的:
public native int hashCode();
本机hashCode 方法实现依赖于JVM。默认情况下,HotSpot 会根据对象的初始内存位置返回随机数,您可以在 source code(函数 get_next_hash)中查看。
根据Java docs这个方法
在合理可行的情况下,hashCode 方法定义为 类 Object 确实为不同的对象返回不同的整数。 (这 通常是通过转换的内部地址来实现 对象转换成整数,但这种实现技术不是 JavaTM 编程语言所要求的。)
但它总是依赖于 JVM 是如何实现 hashCode 方法的。
热点jvm中生成hashcode的Native方法实现:
static inline intptr_t get_next_hash(Thread * Self, oop obj) {
intptr_t value = 0 ;
if (hashCode == 0) {
// This form uses an unguarded global Park-Miller RNG,
// so it's possible for two threads to race and generate the same RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
value = os::random() ;
} else
if (hashCode == 1) {
// This variation has the property of being stable (idempotent)
// between STW operations. This can be useful in some of the 1-0
// synchronization schemes.
intptr_t addrBits = intptr_t(obj) >> 3 ;
value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
} else
if (hashCode == 2) {
value = 1 ; // for sensitivity testing
} else
if (hashCode == 3) {
value = ++GVars.hcSequence ;
} else
if (hashCode == 4) {
value = intptr_t(obj) ;
} else {
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = Self->_hashStateX ;
t ^= (t << 11) ;
Self->_hashStateX = Self->_hashStateY ;
Self->_hashStateY = Self->_hashStateZ ;
Self->_hashStateZ = Self->_hashStateW ;
unsigned v = Self->_hashStateW ;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
Self->_hashStateW = v ;
value = v ;
}
【讨论】:
应该从对象的内容生成自定义哈希码,而不是存储对象的内存位置。
您可以以任何您喜欢的方式为您的对象生成哈希码。但是,有一些规则:
.equals() 的任何两个彼此“相等”的对象必须产生相同的哈希码值。equal 的两个对象可以生成相同的哈希码值。【讨论】: