1. 程式人生 > >深入學習java原始碼——Object類

深入學習java原始碼——Object類

Object class原始碼解析

當我們從jdk包中剛取出來看Object的原始檔時,感覺檔案內容好多哈,其實真正的程式碼沒有多少,大多是註釋,看下面我把註釋全刪了,看起來是不是更加直觀了。

package java.lang;

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); } protected native Object clone() throws CloneNotSupportedException; 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 { if (timeout < 0) { throw new IllegalArgumentException("timeout value is negative"
); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0) { timeout++; } wait(timeout); } public final void wait() throws InterruptedException { wait(0); } protected void finalize() throws Throwable { } }

原始碼通讀

以下原始碼中涉及到的native方法底層均為c/c++語言實現,檢視c/c++語言原始碼請訪問 AndroidXRef網站 檢視 1、registerNatives方法解析

//private static native修飾的方法表示私有的、本地必須實現的原生方法,
//所以我們java開發人員不必擔心此類方法的實現,因為底層已經為我們用C語言實現。
private static native void registerNatives();
    static {//靜態程式碼塊表示類載入時執行此方法
        registerNatives();
}

2、getClass方法解析

//作業系統底層實現,且不被其他子類所覆蓋
//getClass表示獲取物件執行時的類定義資訊
public final native Class<?> getClass();

3、hashCode方法解析

//返回物件的hashCode值
public native int hashCode();

4、equals方法解析

/**
 *比較兩個物件是否相等,相等返回true,不相等返回false。
 *Object作為java中所有類的父類,其實此方法是有侷限性的,我們大多時候需要重寫該
 *方法來達到兩個物件的比較;
 *我們知道所有的物件都擁有引用(記憶體地址)和狀態(資料),同時“==”比較兩個物件的的內
 *存地址,所以說使用Object的equals()方法是比較兩個物件的記憶體地址是否相等,即若
 *object1.equals(object2)為true,則表示object1和object2實際上是引用同一個物件。
 *在JDK中,String、Math等封裝類都對equals()方法進行了重寫。
 */
public boolean equals(Object obj) {
        return (this == obj);
}
//被其他類重寫後的equals方法,可以看到物件內容的比較
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
}

5、clone方法解析

//複製物件方法,返回一個新的物件,在該物件的類無法實現 Cloneable 介面時,丟擲該異常。
//重寫 clone 方法的應用程式也可能丟擲此異常,指示不能或不應複製一個物件。
//這裡要注意與物件引用的賦值區分,如Object a1 = new Object(); Object a2 = a1; 其實還是同一個物件。
protected native Object clone() throws CloneNotSupportedException;

6、toString方法解析

/**
 *該方法這裡返回  當前物件名@此物件雜湊碼的無符號十六進位制表示形式。
 *Integer.toHexString(hashCode()) 以物件的雜湊碼為引數,以16進位制無符號整數形式返回此雜湊碼的字串
 *表示形式。一般在其他類中都會重寫、過載此方法。
 */
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

7、notify方法解析

//其API解釋為 喚醒在此物件監視器上等待的單個執行緒。
//也就是在執行此方法時隨機選擇一個在該物件上呼叫wait方法的執行緒,解除其阻塞狀態。
public final native void notify();

8、notifyAll方法解析

//其API解釋為 喚醒在此物件監視器上等待的所有執行緒。
public final native void notifyAll();

9、 wait方法解析

//在其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法前,導致當前執行緒等待。
public final void wait() throws InterruptedException {
        wait(0);
}
//在其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量timeout前,
//導致當前執行緒等待。
public final native void wait(long timeout) t	hrows InterruptedException;
//在其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法,或者其他某個執行緒中斷當前執行緒,
//或者已超過某個實際時間量timeout前,導致當前執行緒等待。
public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }
        if (nanos > 0) {
            timeout++;
        }
        wait(timeout);
}

10、finalize方法解析

//當垃圾回收器確定不存在對該物件的更多引用時,由物件的垃圾回收器呼叫此方法。
//子類重寫 finalize 方法,以配置系統資源或執行其他清除。
protected void finalize() throws Throwable { }

學完啦,放鬆一下吧!

  • 笑話一:“我給你出個腦筋急轉彎,你說達芬奇密碼的上面是什麼?” “這……太難了吧。不知道。” “笨!達芬奇密碼的上面就是達芬奇帳號啊,那達芬奇密碼的下面是什麼?”“我……這……還是不知道。”“是達芬奇驗證碼”。

  • 笑話二:【程式設計師被提bug之後的反應】 1.怎麼可能;2.在我這是好的,不信你來看看;3.真是奇怪,剛剛還好好的;4.肯定是資料問題;5.你清下快取試試;6.重啟下電腦試試;7.你裝的什麼版本的類庫(jdk)8.這誰寫的程式碼;9.尼瑪怎麼還在用360安全瀏覽器;10.使用者不會像你這麼操作的。

  • 笑話三:客戶被綁,矇眼,驚問:“想幹什麼?” 對方不語,鞭笞之,客戶求饒:“別打,要錢?” 又一鞭,“十萬夠不?” 又一鞭,“一百萬?” 又一鞭。客戶崩潰:“你們TMD到底要啥?” “要什麼?我幫你做專案,寫程式碼的時候也很想知道你TMD到底想要啥!”

  • 笑話四:程式猿跟產品經理一起看電視。每個節目看到一半程式猿就換臺,看到一半就換臺,幾次之後產品經理終於忍無可忍的咆哮:老子剛看出點意思你就換、剛看出點意思你就換,到底還讓不讓人看啦?! 程式猿淡定的盯著電視道:你半路改需求的時候我可沒吱過聲!

  • 笑話五:程式猿的情書 親愛的“物件”: 我能抽象出整個世界,但是我不能抽象出你,因為你在我心中是那麼的具體,所以我的世界並不完整。 我可以過載甚至覆蓋這個世界裡的任何一種方法,但是我卻不能過載對你的思念,也許命中註定了,你在我的世界裡永遠的烙上了靜態的屬性。 而我不慎呼叫了愛你這個方法,當我義無返顧的把自己作為引數傳進這個方法時,我才發現愛上你是一個死迴圈,它不停的返回對你的思念,記在我心裡的堆疊,在這無盡的黑夜中,我的記憶體裡已經再也裝不下別人。 我不停的向系統申請空間,但卻捕獲一個異常:我愛的人不愛我。 為了解決這個異常,我願意虛擬出最後一點記憶體,把所有我能實現的方法地址記入堆疊,並且在棧尾存入最後一個方法:將字串“我愛你,你愛我嗎?”傳遞給你。 如果返回值為真,我將用盡一生去愛你,否則,我將釋放掉所有系統資源。