在java中,Object類是所有類的超類,所有的類都繼承Object類中的方法。 Object類中有12個成員方法,並沒有顯示聲明任何構造方法,而是存在著預設的無參的構造函數。 Object類源代碼分析: 通過Object類源碼可以看到一些方法用native修飾,使用native修飾符修飾的方法需 ...
在java中,Object類是所有類的超類,所有的類都繼承Object類中的方法。
Object類中有12個成員方法,並沒有顯示聲明任何構造方法,而是存在著預設的無參的構造函數。
Object類源代碼分析:
1 package java.lang; 2 3 public class Object { 4 //一個本地方法,具體是用C(C++)在DLL中實現的 5 private static native void registerNatives(); 6 static { 7 registerNatives(); 8 } 9 //返回該Object的運行時類 10 public final native Class<?> getClass(); 11 /* 12 對於Object對象來說,返回對象的地址值。但一般在其他類中都會 13 重寫hashCode方法,使其通過計算得到一個int值(hash值)重寫 14 hashcode方法時必須遵循以下幾點: 15 1、在Java應用的同一次執行過程中,同一對象被多次調用,則他們的 16 hashcode值必然相同。而對於同一個應用的兩次不同的調用,它們的 17 hashcode值可以相同,也有可能不同。 18 2、對於兩個對象來說,如果他們的equals方法比較返回true,那麼這 19 兩個對象的hashcode必然相同。這也解釋了為什麼String類中,如果 20 兩個對象的equals方法相同,則他們的hashcode值一定相同。 21 3、對於兩個對象來說,如果使用equals方法返回為false,則他們的 22 hashcode的值有可能相等也可能不等,(如果不同會提高性能,因為 23 在集合中類判斷兩個對象是否相等,如果其hashcode不等就直接不用 24 判斷equals方法了) 25 4、對於Object對象來說,不同的Object對象的hashcode是不同的, 26 它們返回的是對象的地址,equals返回的也是對象的地址。所以在自 27 己定義的類中如果要添加到集合對象中,最好是要重寫hashcode和 28 equals方法,不然會自動繼承自Object類中的兩個方法根據對象地址 29 來判斷。在重寫自己定義的類時,通常是在類中的根據某個值如 30 name.hashcode();來進行判斷。 31 */ 32 public native int hashCode(); 33 //Object類中equals方法是比較兩個對象的地址是否相同,而一般我們 34 認為兩個對象中只要屬性相同,這兩個對象就相同。所以一般其他類都 35 會重寫equals方法 36 public boolean equals(Object obj) { 37 return (this == obj); 38 } 39 //用來另存一個當前存在的對象 40 protected native Object clone() throws 41 CloneNotSupportedException; 42 //返回一個字元串,用來標識自己 43 public String toString() { 44 return getClass().getName() + "@" + 45 Integer.toHexString(hashCode()); 46 } 47 //喚醒在此對象監視器上等待的單個線程。如果有多個線程等待,則隨 48 機喚醒一個 49 public final native void notify(); 50 //喚醒在此對象監視器上等待的所有線程 51 public final native void notifyAll(); 52 //在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超 53 過指定的時間量前,導致當前線程等待 54 public final native void wait(long timeout) throws 55 InterruptedException; 56 /* 57 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其他 58 某個線程中斷當前線程,或者已超過某個實際時間量前,導致當前線程 59 等待 60 */ 61 public final void wait(long timeout, int nanos) throws 62 InterruptedException { 63 if (timeout < 0) { 64 throw new IllegalArgumentException("timeout value is 65 negative"); 66 } 67 68 if (nanos < 0 || nanos > 999999) { 69 throw new IllegalArgumentException( 70 "nanosecond timeout value out of range"); 71 } 72 73 if (nanos >= 500000 || (nanos != 0 && timeout == 0)) { 74 timeout++; 75 } 76 77 wait(timeout); 78 } 79 /* 80 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導致當 81 前線程等待。換句話說,此方法的行為就好像它僅執行 wait(0) 調用 82 一樣。 83 當前線程必須擁有此對象監視器。該線程發佈對此監視器的所有權並等 84 待,直到其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對 85 象的監視器上等待的線程醒來。然後該線程將等到重新獲得對監視器的 86 所有權後才能繼續執行。 87 */ 88 public final void wait() throws InterruptedException { 89 wait(0); 90 } 91 //當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收 92 器調用此方法 93 protected void finalize() throws Throwable { } 94 }
通過Object類源碼可以看到一些方法用native修飾,使用native修飾符修飾的方法需要非java語言來實現,比如C,C++。這個特征並非java所特有,很多其它的編程語言都有這一機制,比如在C++中,你可以用extern "C"告知C++編譯器去調用一個C的函數。
在定義一個native method時,並不提供實現體(有些像定義一個java interface),因為其實現體是由非java語言在外面實現的。