天天看點

Java Object類源碼閱讀

/**
 * Object類是類層次結構的根類。Object類是每一個類的超類。所有對象,包括數組,
 * 都實作了這個類的方法。
 */
public class Object1 { Object

    private static native void registerNatives();
    static {
        registerNatives();
    }

    /**
     * 傳回這個Object的運作時Class對象。這個Class對象被所代表的類的static synchronized
     * 方法鎖定。
     *
     * 實際的傳回類型是Class<? extends |X|>,|X|是the erasure of 
     * the static type of the expression(什麼意思?),這個表達時調用
     * getClass方法。例如,這個代碼片段不需要造型:
     * Number n = 0;
     * Class<? extends Number> c = n.getClass();
     */
    public final native Class<?> getClass();

    /**
     * 傳回這個對象的哈希值。支援這個方法是為了提高哈希表的性能,例如HashMap。
     * 
     * 關于hashCode通常的約定是:
     * 在一個Java應用程式執行期間,無論何時,在相同的對象上調用這個方法多次,都将傳回相同的
     * 整數,前提是在這個對象上用于equals比較的資訊沒有改變。在應用程式的不同次執行中,這個
     * 傳回值不必保持一緻。
     * 
     * 如果通過equals(Object)方法比較,兩個對象相等,那麼在這兩個對象上調用hashCode
     * 方法将産生相同的整型值。
     * 
     * 通過equals(Object)方法比較,兩個對象不相等,并不要求在這兩個對象上調用hashCode
     * 方法也有不同的傳回值。然而,程式員應該注意到,對不相等的對象産生不同的整型值可能提高
     * 哈希表的執行性能。
     * 
     * 實際上,被Object類定義的hashCode方法對不同的對象确實傳回不同的整數。(這是通過
     * 把對象的内部位址轉化為一個整數來實作的,但是這個實作技巧不被Java程式設計語言需要。)
     */
    public native int hashCode();

    /**
     * 訓示這個其它對象是否和這個對象相等。
     * 
     * equals方法實作非null對象引用之間的相等關系
     * 
     * 它是反身的:對于任何非null引用值x,x.equals(x)應該傳回true。
     * 
     * 它是對稱的:對于任何非null引用值x 和 y, 當且僅當y.equals(x)傳回true時,
     * x.equals(y)才傳回true。
     * 
     * 它是傳遞的:對于任何非null引用值,x,y和z,如果x.equals(y)和
     * y.equals(z)傳回true,那麼x.equals(z)也應該傳回true。
     * 
     * 它是一緻的:對任何非null引用值x和y,多次調用x.equals(y)一直傳回true或者false,前提
     * 是對象上被用在相等比較上的資訊沒有被修改。
     * 
     * 對于任何非null引用值x,x.equals(null)應該傳回false。
     * 
     * Object類的equals方法對象上差别可能性最大的相等關系。也就是說,對于任何
     * 非null引用值x和y,當且僅當這個x和y引用同一個對象時,這個方法才傳回true(
     * x==y是true)
     * 
     * 注意,無論何時重寫這個方法都應該重寫hashCode方法,來保證hashCode方法的約定,約定
     * 指出相等的對象必須有相等的哈希值。
     */
    public boolean equals(Object obj) {
        return (this == obj);
    }

    /**
     * 建立這個對象的一個拷貝。複制的精确意思依賴于這個對象的類。對于任何一個對象x,通用
     * 目的是:
     * x.clone() != x的值為true,
     * x.clone().getClass() == x.getClass()的值為真,
     * 但是這些不是絕對需要的。
     * 典型的,x.clone().equals(x)的值為true,這也不是絕對需要的。
     * 
     * 按照慣例,傳回的對象應該調用super.clone獲得。如果一個類和它的所有超類(除Object)
     * 都遵從這個約定,那麼:
     * x.clone().getClass() == x.getClass()
     * 
     * 按照約定,被這個方法傳回的對象應該獨立于被拷貝的對象。為了實作這個獨立性,修改一個或多個
     * 被傳回對象的域可能是必要的。典型的,這意味着複制包含被複制對象的内部“深度結構”的可變對象,
     * 并且使用副本的引用替換這些對象的引用。如果一個類隻包含基本類型域或者不可變對象的應用,那麼通過
     * super.clone傳回的對象中沒有域需要被修改。
     * 
     * Object類的clone方法執行一個指定的克隆操作。首先,如果對象的類沒有實作接口
     * Cloneable,那麼CloneNotSupportedException将被抛出。注意,所有數組
     * 都實作了Cloneable接口,一個類型為T[]的數組的clone方法的傳回類型是T[],
     * T可以是基本類型,也可以是引用類型。否則,這個方法建立這個對象的類的一個新
     * 執行個體,并且通過這個對象的相關域初始化所有的域,就像指派一樣;這些域的内容沒有自我複制。
     * 是以,這個方法執行這個對象的淺複制,而不是深度複制。
     * 
     * Object類自己沒有實作Cloneable接口,是以在Object類的對象上調用clone将會抛出一個
     * 運作時異常。
     */
    protected native Object clone() throws CloneNotSupportedException;

    /**
     * 傳回這個對象的字元串表示。一般的,toString方法傳回表示這個對象的字元串。傳回的
     * 結果應該是簡明的但是帶有有用資訊的表示,并且是易于人閱讀的。
     * 
     * 建議所有子類都是重寫這個方法。
     * 
     * Object類的toString方法傳回一個字元串,這個字元串由這個對象的類名,@符号,和
     * 這個對象的哈希值的無符号十六進制表示。
     */
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    /**
     * 喚醒一個正在等待這個對象的螢幕的線程。如果一些線程正在這個對象上等待,它們中的一個
     * 将會被喚醒。哪一個被喚醒是不确定的。通過調用一個wait方法,線程在一個對象的螢幕上
     * 等待。
     * 
     * 直到現在占有這個對象鎖的線程放棄鎖,被喚醒的線程才可能被處理。被喚醒的線程和其它一直活躍
     * 并也在競争這個對象上同步的線程一樣競争獲得處理的機會,例如,被喚醒的線程在作為下一個
     * 持有該對象鎖方面沒有可靠的優先級或者優勢。
     * 
     * 這個方法隻能被這個對象的螢幕的擁有者調用。一個線程以下面三種方式之一成為對象螢幕
     * 的擁有者:
     * 通過執行這個對象的一個synchronized執行個體方法
     * 
     * 通過執行在這個對象上同步的語句
     * 
     * 對于Class類的對象,通過執行這個類的同步靜态方法。
     * 
     * 在同一時間,隻有一個線程能擁有對象的螢幕
     */
    public final native void notify();

    /**
     * 喚醒所有等待這個對象的螢幕的線程。一個線程通過調用wait方法在一個對象的螢幕上等待。
     */
    public final native void notifyAll();

    /**
     * 導緻現在的線程去等待,直到另一個線程對這個對象調用notify()或者notifyAll()方法,或者指定
     * 的時間段已經過去。
     * 
     * 現在的線程必須擁有這個對象的螢幕。
     * 
     * 這個方法導緻目前線程(線程 T)把它自己放在這個對象的等待集上,然後放棄這個對象上的所有
     * 等待聲明。出于線程排程的目的,線程T變得不可用的,并且休眠的,直到下面四種情況之一發生
     * 時:
     * 其它線程對這個對象調用notify方法,而且線程T剛好被選中為被激活的線程。
     * 其它線程對這個對象調用notifyAll方法。
     * 其它線程中斷線程T。
     * 指定數量的時間已經過去。如果timeout是0,時間不被考慮,線程一直等待直到被通知。
     * 
     * 線程T從這個對象的等待集中移除,而且對線程排程程式重新變得可用。線程T以正常的方法與其它線程
     * 競争在這個對象上同步的權利;一旦它獲得這個對象的控制,所有在這個對象上的同步聲明将被恢複到
     * 之前的狀态,也就是說,恢複到wait方法調用時的狀态。是以,從wait方法傳回時,這個對象和
     * 線程T的同步狀态和wait方法被調用時的狀态一樣。
     * 
     * 在沒有被通知,中斷,或者逾時時,一個線程依然可以被喚醒,即所謂的虛假喚醒。盡管在實際中
     * 這種情況很少發生,但是應用程式必須通過測試本應該導緻線程被喚醒的條件防止其發生,如果
     * 條件沒有被滿足,線程就應該繼續等待。換句話說,等待應該總是發生在循環中,就像這個:
     *     synchronized (obj) {
     *         while (condition does not hold)
     *             obj.wait(timeout);
     *         ... // Perform action appropriate to condition
     *     }
     *
     * 如果目前線程在等待之前或之中被其它線程中斷,就會抛出InterruptedException。直到這個對象
     * 像上面描述那樣恢複到鎖定狀态,這個異常才會抛出。
     * 
     * 注意,就像wait方法把目前線程放進這個對象的等待集中一樣,它隻能解除這個對象的鎖定;目前
     * 線程在其上同步的其它對象依舊鎖定,當這個線程等待時。
     * 
     * 這個方法應該被這個對象的螢幕的擁有線程調用。
     */
    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 >= 500000 || (nanos != 0 && timeout == 0)) {
            timeout++;
        }

        wait(timeout);
    }


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

    /**
     * 當垃圾回收器得知沒有對這個對象的引用時,這垃圾回收器調用這個方法。子類重寫這個方法
     * 去處理系統資源或者執行其他清理。
     * 
     * finalize的一般約定是,如果活着的線程不能通過任何方法通路到這個對象時,這個方法被
     * 調用,除非是其它準備終結的對象或者類的終結的結果。finalize方法可能采取任何動作,,
     * 包括讓這個對象對其它線程可用;但是,finalize通常的目的是,在這個對象被丢棄之前
     * 執行清理動作。例如,代表一個輸入輸出連接配接的對象的finalize方法可能執行清晰的I/O事物來
     * 中斷連接配接,在這個對象被永久丢棄之前。
     * 
     * Object類的finalize方法執行非特殊的動作;它僅僅正常地傳回。Object類的之類可以重寫
     * 這個方法。
     * 
     * Java語言不保證哪一個線程對任何給定對象調用finalize方法。但是,可以保證調用finalize
     * 方法的線程不會持有使用者可見的同步鎖,當finalize被調用時。如果finalize方法抛出
     * 一個未捕獲異常,異常将被忽略,對象的結束行為将被終止。
     * 
     * 在一個對象上調用finalize方法後,沒有進一步的動作被執行,直到Java虛拟機再次得知活着的
     * 線程沒有任何方法可以通路到這個對象,包括準備結束的其它對象或者類的可能的動作,在這時,
     * 對象可能被丢棄。
     * 
     * 對于任何給定的對象,Java虛拟機隻調用一次finalize方法。
     */
    protected void finalize() throws Throwable { }
}