提到Java
,那就不得不說Object
類。在面試中,你也可能經常遇到Object
類的問題,在這裏總結一番,僅供大家參考。
Object
類是Java
中所有類的根類,即所有的類都繼承了Object
類。其包含的方法如下:
protected Object clone() throws CloneNotSupportedException
創建並返回對象的複製類。通常對於任何對象x,
- x.clone() != x
返回爲true
- x.clone().getClass() == x.getClass()
返回爲true
- x.clone().equals(x)
返回爲true
對象需要被clone
,則需要實現Cloneable
接口。Cloneable
接口只是個標記,沒有任何方法。
更深入的瞭解,對象克隆複製(包含深拷貝、淺拷貝等)請參考 https://www.cnblogs.com/Qian123/p/5710533.html
public boolean equals(Object obj)
判斷兩個對象是否爲同一個對象。equals
方法不能作用於null
對象,具有以下特徵:
- 自反性
對於任何非空引用值x
,始終存在x.equals(x)
爲true
- 對稱性
對於任何非空引用值x
、y
,存在x.equals(y)
爲true
時則y.equals(x)
也一定返回true
- 傳遞性
對於任何非空引用值x
、y
、z
,存在x.equals(y)
爲true
,則y.equals(z)
也爲true
,則x.equals(z)
也一定返回true
- 一致性
對於任何非空引用值x
、y
,不管多次調用x.equals(y)
,則始終返回true
或false
- 對於任何非空引用值x
,始終存在x.equals(null)
爲false
重寫equals()
方法時,應同時重寫hashCode()
方法
面試中經常會問到“請談談
Object
中的==
與equals()
方法的區別”:
其實,在Object
類中這兩者沒有什麼差別,均表示兩對象所指向的內存地址是否相同。但是由於Java
中存在着多態特性,子類可以重寫equals()
方法。譬如,String
類中equals()
表示兩個字符串的值是否相同。
protected void finalize()
當GC(垃圾回收器)確定對象沒有任何引用的時候,調用此方法。子類可以重寫此方法來釋放系統資源或進行其他的清理。
JVM虛擬機不能確定哪個線程來調用對象的finalize()
方法,但是能確定的是調用finalize()
方法的線程不會阻塞用戶線程。如果執行方法時拋出異常,則對應對象的finalize()
方法終止執行。另外,每個對象都只會執行一次finalize()
方法。
public final Class<?> getClass()
返回此對象運行時的類。返回的類對象是由static
鎖方法鎖住的對象。
int hashCode()
爲對象返回哈希值。約定如下:
- 在程序相同執行過程中多次調用同個對象,哈希值必須返回相同。但不是相同調用過程則不必相同;
- 如果兩個對象調用equals()
方法相同,則hashCode()
方法返回值必須相同;
- 如果兩個對象調用equals()
方法不相同,並不需要兩個對象的哈希值不相同。但是編程的時候必須意識到,不同的對象產生不同的哈希值可以提高像HashTable
這樣類的性能。
void notify()
喚醒等待對象鎖的某單個線程。如果有多個線程在等待,則隨機喚醒其中一個,與其他要佔用對象鎖的線程之間競爭鎖。
void notifyAll()
喚醒等待對象鎖的所有線程。喚醒的線程與其他要佔用對象鎖的線程之間競爭鎖。
String toString()
返回對象的String
表示,默認是getClass().getName() + '@' + Integer.toHexString(hashCode())
。JDK規範要求:一般爲了能清晰打印出對象屬性,建議重寫此方法。
筆者在通常項目中,都會寫個
Base
類,重寫toString
方法,返回JSON
字符串。讓所有的自定義類都繼承此Base
類。
void wait()
佔用對象鎖的當前線程來調用,釋放擁有的對象鎖,直到其他線程調用notify()
或者notifyAll()
方法喚醒。
線程調用wait()
方法時,可能存在假喚醒,所以此方法必須在循環中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
// Perform action appropriate to condition
}
void wait(long timeout)
佔用對象鎖的當前線程來調用,釋放擁有的對象鎖,直到其他線程調用notify()
或者notifyAll()
方法喚醒或者指定時間過後自動喚醒。
void wait(long timeout, int nanos)
佔用對象鎖的當前線程來調用,釋放擁有的對象鎖,直到其他線程調用notify()
或者notifyAll()
方法喚醒或者指定時間(1000000*timeout + nanos)過後自動喚醒。