每个自定义类都继承自Object,LinkedListDemo重写hashcode()方法之后就是调用自己的方法了,返回都是99,直接打印的话就是哈希值,一般hashcode()计算出的值为jvm中内存地址,上面的LinkedListDemo自定义后就是99,至于hashcode()底层是怎么计算出来的,可以参考java的源代码:- intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) {
- if (UseBiasedLocking) {
- // NOTE: many places throughout the JVM do not expect a safepoint
- // to be taken here, in particular most operations on perm gen
- // objects. However, we only ever bias Java instances and all of
- // the call sites of identity_hash that might revoke biases have
- // been checked to make sure they can handle a safepoint. The
- // added check of the bias pattern is to avoid useless calls to
- // thread-local storage.
- if (obj->mark()->has_bias_pattern()) {
- // Box and unbox the raw reference just in case we cause a STW safepoint.
- Handle hobj (Self, obj) ;
- // Relaxing assertion for bug 6320749.
- assert (Universe::verify_in_progress() ||
- !SafepointSynchronize::is_at_safepoint(),
- "biases should not be seen by VM thread here");
- BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current());
- obj = hobj() ;
- assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
- }
- }
- // hashCode() is a heap mutator ...
- // Relaxing assertion for bug 6320749.
- assert (Universe::verify_in_progress() ||
- !SafepointSynchronize::is_at_safepoint(), "invariant") ;
- assert (Universe::verify_in_progress() ||
- Self->is_Java_thread() , "invariant") ;
- assert (Universe::verify_in_progress() ||
- ((JavaThread *)Self)->thread_state() != _thread_blocked, "invariant") ;
- ObjectMonitor* monitor = NULL;
- markOop temp, test;
- intptr_t hash;
- markOop mark = ReadStableMark (obj);
- // object should remain ineligible for biased locking
- assert (!mark->has_bias_pattern(), "invariant") ;
-
- if (mark->is_neutral()) {
- hash = mark->hash(); // this is a normal header
- if (hash) { // if it has hash, just return it
- return hash;
- }
- hash = get_next_hash(Self, obj); // allocate a new hash code
- temp = mark->copy_set_hash(hash); // merge the hash code into header
- // use (machine word version) atomic operation to install the hash
- test = (markOop) Atomic::cmpxchg_ptr(temp, obj->mark_addr(), mark);
- if (test == mark) {
- return hash;
- }
- // If atomic operation failed, we must inflate the header
- // into heavy weight monitor. We could add more code here
- // for fast path, but it does not worth the complexity.
- } else if (mark->has_monitor()) {
- monitor = mark->monitor();
- temp = monitor->header();
- assert (temp->is_neutral(), "invariant") ;
- hash = temp->hash();
- if (hash) {
- return hash;
- }
- // Skip to the following code to reduce code size
- } else if (Self->is_lock_owned((address)mark->locker())) {
- temp = mark->displaced_mark_helper(); // this is a lightweight monitor owned
- assert (temp->is_neutral(), "invariant") ;
- hash = temp->hash(); // by current thread, check if the displaced
- if (hash) { // header contains hash code
- return hash;
- }
- // WARNING:
- // The displaced header is strictly immutable.
- // It can NOT be changed in ANY cases. So we have
- // to inflate the header into heavyweight monitor
- // even the current thread owns the lock. The reason
- // is the BasicLock (stack slot) will be asynchronously
- // read by other threads during the inflate() function.
- // Any change to stack may not propagate to other threads
- // correctly.
- }
- // Inflate the monitor to set hash code
- monitor = ObjectSynchronizer::inflate(Self, obj);
- // Load displaced header and check it has hash code
- mark = monitor->header();
- assert (mark->is_neutral(), "invariant") ;
- hash = mark->hash();
- if (hash == 0) {
- hash = get_next_hash(Self, obj);
- temp = mark->copy_set_hash(hash); // merge hash code into header
- assert (temp->is_neutral(), "invariant") ;
- test = (markOop) Atomic::cmpxchg_ptr(temp, monitor, mark);
- if (test != mark) {
- // The only update to the header in the monitor (outside GC)
- // is install the hash code. If someone add new usage of
- // displaced header, please update this code
- hash = test->hash();
- assert (test->is_neutral(), "invariant") ;
- assert (hash != 0, "Trivial unexpected object/monitor header usage.");
- }
- }
- // We finally get the hash
- return hash;
- }
复制代码 |