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 { }