hashCode在Object类中实现,在此先不做引申,仅介绍一个对象的hashCode是怎么产生的:
首先查看Java.lang.Object:
// Object is the root of the class hierarchy.
// All objects, including arrays, implement the methods of this class.
public class Object {
// Returns a hash code value for the object. This method is
// supported for the benefit of hash tables such as those provided by
// HashMap
public native int hashCode();
}
在Object类里是没有直接实现hashCode()方法的,我们只知道这是一个native方法,即非java实现的。
它的实现可以在OpenJDK里找到(openjdk/jdk/src/share/native/java/lang/Object.c):
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
可以知道又和JVM_IHashCode有关;
再找到JVM_IHashCode的定义(openjdk\hotspot\src\share\vm\prims\jvm.cpp):
// java.lang.Object ///////////////////////////////////////////////
JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))
JVMWrapper("JVM_IHashCode");
// as implemented in the classic virtual machine; return 0 if object is NULL
return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;
JVM_END
可以知道又和FastHashCode方法有关(openjdk\hotspot\src\share\vm\runtime\synchronizer.cpp);
其中,FastHashCode中又有:
hash = get_next_hash(Self, obj); // allocate a new hash code
可知实现在get_next_hash()方法中,其核心的代码是:
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 ;
}
其中在thread.cpp中有定义:
// thread-specific hashCode stream generator state - Marsaglia shift-xor form
_hashStateX = os::random() ;
_hashStateY = 842502087 ;
_hashStateZ = 0x8767 ; // (int)(3579807591LL & 0xffff) ;
_hashStateW = 273326509 ;
于是我们可以知道JDK8的hashCode()的产生是基于一个随机数和三个确定数的,至于为什么get_next_hash()方法中的核心代码是这样,这要援引一篇论文:
Xorshift RNGs
再深入就要涉及数学的推导和矩阵的运算了,我也没有完全吃透,有兴趣的可以看看这篇论文。
思考:
1.为什么JDK8的hashCode不引入对象的地址参与运算呢?
2.既然是基于hash,那么必然有几率产生碰撞,碰撞产生时如何处理?
3.hashCode和equal方法的联系
4.hashCode和hashMap的联系