JDK原始碼解析系列之object

雨露發表於2019-01-19

JDK原始碼之Object類

1 private static native void registerNatives();

Java中,用native關鍵字修飾的函式表明該方法的實現並不是在Java中去完成,而是由C++去完成,並被編譯成了.dll,由Java去呼叫。方法的具體實現體在dll檔案中,對於像Window,Linux,Mac不同平臺,其具體實現有所不同,主要作用是將C++的方法對映到Java中,實現方法命名的解藕。

2 public final native Class<?> getClass();

clone()方法又是一個被宣告為native的方法,因此,我們知道了clone()方法並不是Java的原生方法,具體的實現是有C++完成的,其目的是建立並返回此物件的一個副本,在List集合中,會經常用到,比如說,list集合擴容。

3 public final native Class<?> getClass();

在Java中,每一個類都有相同的特徵和行為的例項的抽象並進行描述,例如,都具有類的名稱,由類載入器去載入,
都有包,父類的屬性和方法,Java中有專門定義的一個類,class,可以通過getClass方法,就可以獲取類的所有特徵,在Java的反射技術中,大量使用這個方法。

4 public boolean equals(Object obj);

在此方法中,返回的結果是this == obj ,可知,Object的原生的equals()方法呼叫的正是==,與==具有相同的含義。在object類中,此標尺即為==。當然,這個標尺不是固定的,其他類中可以按照實際的需要對此標尺含義進行重定義。如String類中則是依據字串內容是否相等來重定義了此標尺含義。如此可以增加類的功能型和實際編碼的靈活性。當然了,如果自定義的類沒有重寫equals()方法來重新定義此標尺,那麼預設的將是其父equals(),直到object基類。

5 public native int hashCode();

hashCode()方法返回一個整形數值,表示該物件的雜湊碼值。在Java應用程式程式執行期間,對於同一物件多次呼叫hashCode()方法時,其返回的雜湊碼是相同的,前提是將物件進行equals比較時所用的標尺資訊未做修改。在Java應用程式的一次執行到另外一次執行,同一物件的hashCode()返回的雜湊碼無須保持一致。如果兩個物件相等(依據:呼叫equals()方法),那麼這兩個物件呼叫hashCode()返回的雜湊碼也必須相等;反之,兩個物件呼叫hasCode()返回的雜湊碼相等,這兩個物件不一定相等。以集合類中,以Set為例,當新加一個物件時,需要判斷現有集合中是否已經存在與此物件相等的物件,如果沒有hashCode()方法,需要將Set進行一次遍歷,並逐一用equals()方法判斷兩個物件是否相等,此種演算法時間複雜度為o(n)。通過藉助於hasCode方法,先計算出即將新加入物件的雜湊碼,然後根據雜湊演算法計算出此物件的位置,直接判斷此位置上是否已有物件即可。

6 public String toString();

getClass()返回物件的類物件,getClassName()以String形式返回類物件的名稱(含包名)。
Integer.toHexString(hashCode())則是以物件的雜湊碼為實參,以16進位制無符號整數形式返回此雜湊碼的字串表示形式。例如呼叫toString,就會返回以包名類名和16進位制連線的名字。

7 public final native void notify();

喚醒所有在這個物件的監視器上等待的執行緒,執行緒通過呼叫一個物件來監視物件的監視器。在當前執行緒放棄對該物件的鎖定之前,喚醒執行緒將無法繼續進行。被喚醒的執行緒將以通常的方式與可能在此物件上積極競爭同步的任何其他執行緒競爭;例如,被喚醒的執行緒在成為下一個鎖定此物件的執行緒時沒有可靠的特權或缺點。

8 public final native void notifyAll();

同 notify ,其所線上程不會立即釋放所持有的鎖,直到其所在同步程式碼塊中的程式碼執行完畢,此時釋放鎖,因此,如果其同步程式碼塊後還有程式碼,其執行則依賴於JVM的執行緒排程

9 public final native void wait(long timeout) throws InterruptedException;

wait(…)方法呼叫後當前執行緒將立即阻塞,且適當其所持有的同步程式碼塊中的鎖,直到被喚醒或超時或打斷後且重新獲取到鎖後才能繼續執行;

10 protected void finalize() throws Throwable { }

Object中定義finalize方法表明Java中每一個物件都將具有finalize這種行為,其具體呼叫時機在:JVM準備對此對形象所佔用的記憶體空間進行垃圾回收前,將被呼叫。由此可以看出,此方法並不是由我們主動去呼叫的(雖然可以主動去呼叫,此時與其他自定義方法無異)

11 為什麼所有的類的父類都是Object類,而有些原始碼並沒有繼承Object

在編譯原始碼時,當遇到沒有父類的類時,編譯器會將其指定一個預設的父類(一般為Object),而虛擬機器在處理到這個類時,由於這個類已經有一個預設的父類了,因此,VM仍然會按著常規的方法來處理每一個類。對於這種情況,從編譯後的二進位制角度來看,所有的類都會有一個父類。

相關文章