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方法
哈希码的通用规约如下:
- 在java程序执行过程中,在一个对象没有被改变的前提下,无论这个对象被调用多少次,hashCode方法都会返回相同的整数值。对象的哈希码没有必要在不同的程序中保持相同的值。
- 如果2个对象使用equals方法进行比较并且相同的话,那么这2个对象的hashCode方法的值也必须相等。
- 如果根据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 { }