學妹問我 Object 方法,我剛好都會

Object 的重要性

學習 Java 的同學都知道,Object 是一個很重要的類,它是所有類的父類。在日常開發中我們可能經常要與 Object 打交道,如果還不熟悉 Object ,肯定是說不過去的。

我認爲熟悉 Java 很難,熟悉 Object 卻不難,單單一個 Object 尚且不敢言勝,我們又哪有勇氣去深入剖析 Java 的內核呢?

Object 的源碼

紙上談兵終歸是落了下乘,想要真正熟悉 Object ,我們還得從源碼入手。

package java.lang;

import jdk.internal.HotSpotIntrinsicCandidate;

public class Object {

    @HotSpotIntrinsicCandidate
    public Object() {}

    @HotSpotIntrinsicCandidate
    public final native Class<?> getClass();

    @HotSpotIntrinsicCandidate
    public native int hashCode();

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

    @HotSpotIntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;

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

    @HotSpotIntrinsicCandidate
    public final native void notify();

    @HotSpotIntrinsicCandidate
    public final native void notifyAll();

    public final void wait() throws InterruptedException {
        wait(0L);
    }

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

    public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
        if (timeoutMillis < 0) {
            throw new IllegalArgumentException("timeoutMillis value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
            timeoutMillis++;
        }

        wait(timeoutMillis);
    }

    @Deprecated(since="9")
    protected void finalize() throws Throwable { }
}

從源碼中我們可見,Object 共有 11 個方法。而且大部分方法前面都帶有 native 修飾符,這個修飾符表示本方法爲本地方法,該方法的實現並不是 Java,而是 C/C++,而且方法的實現並不在本文件中。

爲什麼這部分的方法的實現要使用別的語言,而不能是 Java 呢?一方面,Object 的方法大部分與底層有關,且 Java 不能操作操作系統底層,但是可以通過 JNI 接口調用其他語言來實現對底層的訪問,另外一個角度,使用本地方法可能在性能方面更有優勢一點。

對 Object 各個方法的簡介

getClass 方法

	@HotSpotIntrinsicCandidate
    public final native Class<?> getClass();

該方法是一個本地方法,由 final 修飾可知該方法不允許子類重寫,它返回一個 Class 對象,該對象使用的是哪一個類的構造函數,返回的就是哪一個類的 Class 對象。該方法經常在反射機制中被用到。

hashCode 方法

	@HotSpotIntrinsicCandidate
    public native int hashCode();

該方法是一個本地方法,返回對象的哈希碼。

equals 方法

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

一般用於比較兩個對象是否相等,在未被子類重寫的情況下 equals 用於比較兩個對象的內存地址是否相等。

clone 方法

	@HotSpotIntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;

該方法是一個本地方法,用於創建並返回當前對象的一份拷貝。

toString 方法

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

該方法返回對象的字符串表示形式,其實實際上返回的是一個 “類名@哈希碼” 的字符串。

notify 方法

	@HotSpotIntrinsicCandidate
    public final native void notify();

該方法是一個本地方法,由 final 修飾可知該方法不允許子類重寫,作用爲喚醒一個在此對象鎖上等待的線程,如果有多個線程在等待則只會喚醒一個。

notifyAll 方法

	@HotSpotIntrinsicCandidate
    public final native void notifyAll();

該方法是一個本地方法,由 final 修飾可知該方法不允許子類重寫,作用與 notify 相似,其區別爲 notifyAll 會喚醒在此對象鎖上等待的所有線程,而不僅僅是一個。

wait 方法

	public final void wait() throws InterruptedException {
        wait(0L);
    }

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

    public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
        if (timeoutMillis < 0) {
            throw new IllegalArgumentException("timeoutMillis value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
            timeoutMillis++;
        }

        wait(timeoutMillis);
    }

該方法是一個本地方法,由 final 修飾可知該方法不允許子類重寫,一般與 notify/notifyAll 配套使用,作用爲讓當前正在執行的線程進入線程阻塞狀態的等待狀態,它只能在同步代碼塊或同步方法中調用,且執行後當前線程釋放鎖。

finalize 方法

	@Deprecated(since="9")
    protected void finalize() throws Throwable { }

finalize 方法與 Java 的垃圾回收機制有關,在垃圾回收器準備釋放對象佔用的存儲空間時,會首先調用其 finalize 方法(每個對象的 finalize 方法只能被執行一次),如果它能夠與引用鏈(GC-Roots)上的任何一個對象關聯,就可以存活下來,否則將會被回收。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章