【Java面試提問解讀】Object類九大方法
面試公司:位元組跳動西瓜視訊
面試崗位:後臺開發日常實習生
面試輪次:第一次面試
前言:我們知道Object類是所有的Java物件隱式繼承的類,而在Object類上有九大方法,這是一個基本需要掌握的知識點。在這個提問點上有多個可衍生的問題
Object類有哪些方法並分別簡單介紹
-
getClass()
:這是一個final
方法,亦即不可重寫。其作用是獲取物件的執行時Class
。 -
hashCode()
:獲取物件的雜湊值,一般情況下是根據物件的地址或者字串或者數字計算。 -
equals()
:判斷兩個物件是否相等。 -
clone()
:這是一個protected
方法。實現物件的淺複製,只有當物件實現了Cloneable
接口才可以呼叫該方法,否則丟擲CloneNotSupportedException
異常。 -
toString()
:返回一個能夠表示該物件的字串,一般來說該字串應該是簡明而有意義的,且儘量所有的子類都應該重寫該方法。 -
notify()
:喚醒在該物件上等待的某個執行緒,如果有多個執行緒在該物件上等待,那麼按照一定的演算法喚醒其中一個。 -
notifyAll()
:喚醒在該物件上等待的所有執行緒 -
wait()
:使當前執行緒在該物件上等待。 -
finalize()
:這是一個protected
方法。當物件被釋放時,該方法則會被呼叫進而程式設計師可通過該方法釋放JVM無法管理的記憶體以避免記憶體洩漏。
比較hashCode()
與equals()
與==
-
首先比較
equals()
與==
:簡單來說,
==
是值的比較,而equals()
是物件的比較。我們知道Java的兩大型別分別是原始型和引用型,不管原始型還是引用型都有基本的值,原始型的值就是本身的變數值,而引用型的值是指向堆中某個物件的引用。==
就是比較這個基本的值,而equals()
方法則是對物件進行比較,這樣也就是兩個引用型指向的物件之間的比較。也就是說,
==
為true
的是同一個物件,其equals()
一定為true
;而equals()
為true
的是邏輯上相等的物件,可能是同一個也可能不是。然而,參考之下
equals()
在Object
類的實現,Java預設equals()
是通過==
進行的,也就是說,只有當我們重寫該方法後,一般才是通過物件來判斷相等。
public boolean equals(Object obj) { return (this == obj); }
-
然後比較
hashCode()
與equals()
:首先最重要的是
hashCode()
相等並不表示物件相等,equals()
為true
則物件一定相等,且Java要求此時的計算出的hashCode()
必須一致。我們之前提到
hashCode()
是對於物件的雜湊值的計算,聯想資料結構時對雜湊表的瞭解,沒有某個演算法能對每個不同的物件計算出不同的雜湊值,所以存在不同的物件雜湊值相等的可能性,而equals()
的實現就是我們對物件相等的邏輯判斷,但往往equals()
較hashCode()
效率低。所以實際上的判斷物件是否相等是先判斷
hashCode()
是否相等,如果不相等則物件肯定不相等,如果相等則繼續呼叫equals()
判斷物件是否相等。
詳述wait()
與notify()
作用
該問題如有作業系統原理相關的知識在理解上會更好(以下尚未深入到應用層)
-
根據個人理解,
wait()
與notify()
非常類似於訊號量原語,將物件視為訊號量,將在物件上等待的執行緒數量視為訊號量的值。 -
首先
wait()
會使當前執行緒在該物件上進入阻塞,其過載方法可設定超時間隔,可以有多個執行緒在該物件上等待。其進入排程的情況有notify()
,notifyAll()
和超時(不考慮InterruptedException
)。 -
然後
notify()
可以使當前執行緒上的某一個執行緒進入排程。該執行緒的選擇決定於具體的排程方案,幾乎相當於隨機,不可對執行緒的選擇做預先的猜測判斷;而notifyAll()
則是使當前物件的所有執行緒進入排程。
詳述finalize()
作用
-
Java的GC只負責物件記憶體相關的清理,所有其他資源的清理必須由程式設計師手動編寫,否則可能導致記憶體洩漏,因此某些物件會有
close()
方法。 -
而
finalize()
是確定的當物件被GC回收時必然呼叫的方法,假設有資源持續在整個物件的生命週期裡,可以將額外的資源在finalize()
裡進行回收 -
finalize()
可以被使用者自己呼叫,但這種呼叫不會導致物件被銷燬 -
GC時,
finalize()
裡丟擲的異常,如未被捕獲處理,只會導致該物件的finalize()
執行退出,而不會導致GC終止。
結語:這一部分面試的時候我雖然曾經學習而且理解過,但幾乎全忘了,因為課程專案基本不會涉及到上述的大部分方法。但又確確實實在實際工作中很有用,而且屬於個人的硬實力,所以基本上還是會作為面試的主要考核內容,作此記錄,以便之後複習。
如有錯誤,還請各位在下指出,以便不誤導。