JDK1.8源码解读之 Object

248 阅读4分钟

概述


在Java语言中,Object类是所有类的父类。所有的对象,包括array,都实现了Object的方法。

继承关系


Object是所有类的父类。

成员属性


构造器


源码中并没有Object的构造方法,但是Java语言中,只要类中没有提供构造方法,编译器会在编译期间给改类一个默认的空的构造方法。

关键方法


getClass()

返回Object运行时的类

public final native Class<?> getClass();

// 示例:
Object number = new Integer(2);
System.out.println(number.getClass());
>> class java.lang.Integer
hashCode()

返回对象的hash code。

public native int hashCode();

方法说明:hashCode的常规协定是:

  1. 在java应用程序执行期间,在对同一对象多次调用hashCode()方法时,必须一致地返回相同的整数,前提是将对象进行equals比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
  2. 如果根据equals(object)方法,两个对象是相等的,那么对这两个对象中的每个对象调用hashCode方法都必须生成相同的整数结果。
  3. 如果根据equals(java.lang.Object)方法,两个对象不相等,那么对这两个对象中的任一对象上调用hashCode()方法不要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
+ equals()

判断两个对象是否“相等”

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

源码注释里,清楚的解释了equals()判断规则: 以下规则中的变量都不能是null

  1. 反身性,那么x.equals(x)恒成立
  2. 对称性,如果x.equals(y), 那么y.equals(x)
  3. 传递性,如果x.equals(y),并且y.equals(z),那么x.equals(z),
  4. 一致性,多次调用x.equals(y),如果x,y在此期间没有被修改过,那么会恒定返回固定的值(true或者false)
  5. 对于任何非null的引用变量x,x.equals(null) 都等于 false 注释的最后还有最重要的一句话: 当且仅当两个x和y引用同一个对象的时候,x.equals(y)才会返回true
+ toString()

返回对象的“文字上的”表示

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

方法说明: 一般建议子类重写Object的toString方法,如果没重写会返回:类名@哈希值

+ notify()

不能被重写,用于唤醒一个在因等待该对象(调用了wait方法)被处于等待状态(waiting 或 time_wait)的线程,该方法只能同步方法或同步块中调用

public final native void notify();

+ notifyAll()

不能被重写,用于唤醒所有在因等待该对象(调用wait方法)被处于等待状态(waiting或time_waiting)的线程,该方法只能同步方法或同步块中调用

public final native void notifyAll();
+ wait()

不能被重写,用于在线程调用中,导致当前线程进入等待状态(time_waiting),timeout单位为毫秒,该方法只能同步方法或同步块中调用,超过设置时间后线程重新进入可运行状态

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

该方法还有两个重载方法,是对等待时间做了一些调整:

// 无限等待
public final void wait() throws InterruptedException {
    wait(0);
}

// 等待固定时间
public final void wait(long timeout, int nanos) throws InterruptedException {
    ... //省略,具体代码请看源码。
}
# finalize()

这个方法用于当对象被回收时调用,这个由JVM支持,Object的finalize方法默认是什么都没有做,如果子类需要在对象被回收时执行一些逻辑处理,则可以重写finalize方法。

protected void finalize() throws Throwable {
}

常见问题


notify()/notifyAll()/wait()方法注意点?
  • 他们都是final方法,不能被重写。
  • 必须在同步代码块,或者同步方法内使用,三个方法均需要获得锁才能执行。
  • wait() 会释放当前锁,当前线程进入阻塞状态。直到其他线程执行了notify/notifyAll方法,才会才会唤醒一个或者多个处于阻塞状态的线程。
  • 一定要先执行wait方法,然后再执行notify/notifyAll,否则是无法唤醒线程的。

结语


这里比较值得注意的地方是wait/notify/notifyAll方法。和多线程相关,以后还会涉及到更多多线程相关的内容。

希望和大家多多交流


我16年毕业以后,做的是前端,目前打算深入学习java开发。内容有任何问题,欢迎各位小伙伴们指正,也希望小伙伴们给我点赞和关注,给我留言,一起交流讨论,共同进步。