Object類是Java中所有類的父類,所以對其的認識是十分重要的。
下面是我對Object類中個方法的認識(結合了代碼中的注釋以及看過的一些書)
public class Object { //其主要作用是將C/C++中的方法映射到Java中的native方法,實現方法命名的解耦。函數的執行是在靜態代碼塊中執行的,在類首次進行載入的時候執行。 private static native void registerNatives(); static { registerNatives(); } //返回此Object的運行時對象,返回的class對象由synchronized鎖定 public final native Class<?> getClass(); /** * 特點: * 1、每當在執行Java應用程式期間多次在同一對象上調用它時,{@code hashCode}方法必須始終 * 返回相同的整數,前提是不修改對象上的{@code equals}比較中使用的資訊。 從應用程式的一 * 次執行到同一應用程式的另一次執行,該整數不需要保持一致。 * 2、如果兩個object根據equals判定真,則hashcode必須返回相同的值 * 3、如果兩個object不equal,hashcode可以相同也可以不同。 */ public native int hashCode(); /** * Object的equals()方法比較的是對象在記憶體中的地址。 * 對於所有的非Null 參考: * 自反性:x.equals(x)為true * 對稱性:如果x.equals(y)為true,則y.equals(x)為true * 傳遞性:如果x.equals(y)為true,y.equals(z)為true,則x.equals(z)為true * 一致性:對於任何非null的引用值x與y,假設對象上equals比較中的資訊沒有被修改,則多次調用x.equals(y)始終返回true或者始終返回false * 對於任何非Null 參考值x,x.equal(null)應返回false */ public boolean equals(Object obj) { return (this == obj); } /** * 建立並且返回一個對象的複製,clone()的正確調用是需要實現Cloneable介面,如果沒有實現Cloneable介面,並且子類直接 * 調用Object類的clone()方法,則會拋出CloneNotSupportedException異常。 * x.clone() != x * x.clone().getClass() == x.getClass(); * x.clone().equals(x); * 這些運算式一般都為true,但是並不是絕對需要的。 * 一般而言,clone()是將這個對象複製一次,變成兩個對象,都有著自己的記憶體空間,而不是只建立一個引用,所以x.clone() != x;為true * x.clone().getClass() == x.getClass();為true說明兩個對象的運行時對象相同 * x.clone.equals(x);依賴於equals()方法的重寫,如果只是調用Object的equals()方法,那麼這個運算式返回false,因為Object的equals() * 方法比較的是對象的地址。 * * 深拷貝和淺拷貝: * 淺拷貝是將原始對象中的資料型欄位拷貝到新對象中去,將引用型欄位的“引用”複製到新對象中去, * 不把“引用的對象”複製進去,所以原始對象和新對象引用同一對象,新對象中的引用型欄位發生變化會 * 導致原始對象中的對應欄位也發生變化。深拷貝是在引用方面不同,深拷貝就是建立一個新的和原始字 * 段的內容相同的欄位,是兩個一樣大的資料區段,所以兩者的引用是不同的,之後的新對象中的引用型字 * 段發生改變,不會引起原始對象中的欄位發生改變。 * */ protected native Object clone() throws CloneNotSupportedException; //返回類的名稱加上@,然後 加上此類的雜湊碼的16進位表示 public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } /** * 喚醒正在此對象上等待的一個線程。 如果有多個線程正在等待此對象,則選擇其中一個線程被喚醒。 選擇是任意的,由JVM實施決定。 * 線程通過調用{@code wait}方法等待擷取對象。 * 在當前線程放棄對該對象的鎖定之前,喚醒的線程(就緒狀態)將無法繼續。喚醒的線程將以普通的方式與可能正在競爭同步此對象的任何其他線程 * 競爭; 例如,喚醒線程在成為鎖定此對象的下一個線程時沒有可靠的特權或劣勢。 * 這個方法只能被對象的所有者線程調用,線程以以下三種方式成為對象的所有者: * 1、通過執行該對象的同步執行個體方法 * 2、通過執行該對象的同步代碼塊 * 3、通過執行該對象的靜態同步方法。 * 同一時刻只能有一個線程持有該對象的鎖 */ public final native void notify(); //使所有正在等待池中等待同一共用資源的全部線程從等待狀態退出,進入可運行狀態,讓它們競爭對象的鎖,只有獲得鎖的線程才能進入就緒狀態 public final native void notifyAll(); /** * 使當前線程進入等待狀態,直至其他線程調用notify()或者notifyAll()方法,又或是達到指定時間 * 當前線程必須持有該對象的鎖。 * 這個方法使得當前線程T 進入該對象的等待隊列中,直到以下四件事情發生: * 1、有其他線程調用了notify()方法,且線程T正好被選為喚醒的線程 * 2、有其他線程調用了notifyAll()方法 * 3、其他線程調用了interrupt()方法中斷線程T * 4、等待的時間超過了wait制定的時間。但是,如果{@code timeout}為零,則不考慮即時,線程只是等待其他線程喚醒。 * 線程被喚醒後就從Object的等待集合中刪除,並且能夠被重新調度 * * */ 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); } /** * 當記憶體回收行程認為一個對象沒有其他引用時,調用該方法。子類重寫{@code finalize}方法以處理系統資源或執行其他清理。 * 《深入理解Java虛擬機器》書中談到: * 即使在可達性分析演算法中不可達的對象,也並非是“非死不可”的。要真正宣告一個對象死亡,至少要經曆兩次標記過程: * 1、如果對象在進行可達性分析後發現沒有與GC Roots相串連的引用鏈,那它將會被第一次標記並且進行一次篩選,篩選的 * 條件是此對象是否有必要執行finalize()方法。當對象沒有覆蓋finalize()方法,或者finalize()方法已經被虛擬機器調用 * 過,則虛擬機器認為該對象死亡。 * 2、如果需要執行finalize()方法,那麼對象會被放置到一個F-Queue的隊列中。finalize()方法是對象逃脫死亡的最後一次 * 機會。GC對F-Queue中的對象進行第二次標記,如果對象在finalize()方法中成功拯救了自己,則GC在第二次標記時將對象移出 * “即將回收”集合;如果對象沒有逃脫,那就真的GG了 * 注意 finalize()方法只能被系統調用一次。如果對象面臨第二次記憶體回收,finalize()方法不會被執行。 */ protected void finalize() throws Throwable { }}