关于Object中的hashCode方法

来源:互联网 发布:淘宝美工好找工作吗 编辑:程序博客网 时间:2024/06/07 23:01

通过jdk源码可看到public native int hashCode();此方法是交给C++等实现的,在Oracle的jdk中看不到此实现方法,但是在OpenJDK中可看到,如下

// hashCode() generation ://// Possibilities:// * MD5Digest of {obj,stwRandom}// * CRC32 of {obj,stwRandom} or any linear-feedback shift register function.// * A DES- or AES-style SBox[] mechanism// * One of the Phi-based schemes, such as://   2654435761 = 2^32 * Phi (golden ratio)//   HashCodeValue = ((uintptr_t(obj) >> 3) * 2654435761) ^ GVars.stwRandom ;// * A variation of Marsaglia's shift-xor RNG scheme.// * (obj ^ stwRandom) is appealing, but can result//   in undesirable regularity in the hashCode values of adjacent objects//   (objects allocated back-to-back, in particular).  This could potentially//   result in hashtable collisions and reduced hashtable efficiency.//   There are simple ways to "diffuse" the middle address bits over the//   generated hashCode values://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.     // 地址基础上hack     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 ;  }  value &= markOopDesc::hash_mask;  if (value == 0) value = 0xBAD ;  assert (value != markOopDesc::no_hash, "invariant") ;  TEVENT (hashCode: GENERATE) ;  return value;}

可看到获得hash值得方法有5种,其中包括随机数、地址基础上进行处理、默认值1、直接地址、一个称为Marsaglia的方法,其中默认的就是第5种,即Marsaglia的方法。
参考:Java的Object.hashCode()的返回值到底是不是对象内存地址?

另外String的hashCode被重写。是根据String值生成的。

原创粉丝点击