Object 源码解析

Object的源码结构如下,Objec有以下方法

public class Object {

    private static native void registerNatives();
    static {
        registerNatives();
    }

    public final native Class<?> getClass();

    public native int hashCode();

    public boolean equals(Object obj) {
        return (this == obj);
    }

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    public final native void notify();

    public final native void notifyAll();

    public final native void wait(long timeout) throws InterruptedException;

    public final void wait(long timeout, int nanos) throws InterruptedException;

    public final void wait() throws InterruptedException;

    protected void finalize() throws Throwable { }
}

  

1、public final native Class<?> getClass();

getClass是一个native方法,final的不允许子类重写

返回当前运行时对象的Class对象,如下定义的n类型为Number,但是Java中默认的类型为Integer类,所以返回的是java.lang.Integer

        Number n = 0;
        System.out.println(n.getClass());  // class java.lang.Integer

  

2、public native int hashCode();

hashCode也是一个native方法

哈希码的通用规约如下:

  1. 在java程序执行过程中,在一个对象没有被改变的前提下,无论这个对象被调用多少次,hashCode方法都会返回相同的整数值。对象的哈希码没有必要在不同的程序中保持相同的值。
  2. 如果2个对象使用equals方法进行比较并且相同的话,那么这2个对象的hashCode方法的值也必须相等。
  3. 如果根据equals方法,得到两个对象不相等,那么这2个对象的hashCode值不需要必须不相同。但是,不相等的对象的hashCode值不同的话可以提高哈希表的性能。

通常情况下,不同的对象产生的哈希码是不同的。默认情况下,对象的哈希码是通过该对象内部地址转换成一个整数来实现的。

String的hasCode方法实现如下:

public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

hashCode的源码如下

static inline intptr_t get_next_hash(Thread * Self, oop obj) {
  intptr_t value = 0 ;
  if (hashCode == 0) {
    // 根据Park-Miller伪随机数生成器生成的随机数
     value = os::random() ;
  } else
  if (hashCode == 1) {
     // 此类方案将对象的内存地址,做移位运算后与一个随机数进行异或得到结果
     intptr_t addrBits = cast_from_oop<intptr_t>(obj) >> 3 ;
     value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
  } else
  if (hashCode == 2) {
     value = 1 ;            // 返回固定的1
} else
  if (hashCode == 3) {
     value = ++GVars.hcSequence ;  // 返回一个自增序列的当前值
  } else
  if (hashCode == 4) {
     value = cast_from_oop<intptr_t>(obj) ;  // 对象地址
  } else {
     // 通过和当前线程有关的一个随机数+三个确定值
     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;
}

 java6、7默认返回随机数

java8默认是通过当前线程相关的一个随机数+三个确定值,运用Marsaglia’s xorshift scheme随机三方得到一个随机数。 

参考:https://blog.csdn.net/changrj6/article/details/100043822

  

3、equqls方法

public boolean equals(Object obj) 

比较两个对象是否相等,Object类的默认实现,就是比较2个对象的内存地址是否相等

    public boolean equals(Object obj) {
        return (this == obj);
    }  

equals方法在非空对象引用上的特性

1)、reflexive,自反性。任何非空引用值x, 对于x.equals(x)必须返回true

2)、symmetric,对称性。 任何非空引用值x和y,如果x.equals(y)为true,那么y.equals(x)也必须为true

3)、transitive,传递性,任何非空引用值x、y和z,如果x.equals(y)为true,并且y.equqls(z)为true, 那么x.equqls(z)也必定为true

4)、consistent,一致性。任何非空引用值x和y,多次调用x.equals(y) 始终为true或者始终为false,前提是对象上equals比较中所用的信息没有被修改

5)、对于任何非空引用值x, x.equals(null)都应返还false

4、clone方法

protected native Object clone() throws CloneNotSupportedException;

clone是一个native方法,一般情况下,对于任何对象x, x.clone() != x 为true, x.clone().getClass() == x.getClass() 也为true

5、toString()方法

Object对象的默认实现,即输出类的名字 @实例哈希码的16进制

public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

 

6、notify方法 

public final native void notify();

是一个native方法, 并且是final不允许子类重写

 唤醒一个在此对象监视器上等待的线程(监视器相当于锁的概念)。一个线程在对象监视器等待可以调用wait方法。

7、public final native void notifyAll();

和notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。

8、public final native void wait(long timeout) throws InterruptedException;

wait是native方法,也是final的,不允许子类重写

wait方法会让当前线程等待直到另外一个线程调用对象的notify或者notifyAll方法,或者超过参数设置的timeout超时时间。

9、public final void wait(long timeout, int nanos) throws InterruptedException;

和wait方法一样,多了一个参数 nanos 毫微秒 

10、public final void wait() throws InterruptedException;

没有超时时间的wait方法

11、finalize方法

默认实现是不进行任何操作

protected void finalize() throws Throwable { }

原文地址:https://www.cnblogs.com/linlf03/p/12624924.html