概述
Object類是類層次結(jié)構(gòu)的根,Java中所有的類從根本上都繼承自這個類衡奥。Object類是Java中唯一沒有父類的類。其他所有的類吕喘,包括標(biāo)準(zhǔn)容器類赘那,比如數(shù)組,都繼承了Object類中的方法氯质。
Object類位于java.lang包中募舟,java.lang包包含著Java最基礎(chǔ)和核心的類,在編譯時會自動導(dǎo)入闻察。Object類沒有定義屬性拱礁,一共有13個方法,具體的類定義結(jié)構(gòu)如下圖:
Object類中的方法
Java中的每個類都具有定義在Object類中的這些方法辕漂。
構(gòu)造方法
public Object()
大部分情況下呢灶,Java中通過形如 new A(args..)形式創(chuàng)建一個屬于該類型的對象。其中A即是類名钉嘹,A(args..)即此類定義中相對應(yīng)的構(gòu)造函數(shù)鸯乃。通過此種形式創(chuàng)建的對象都是通過類中的構(gòu)造函數(shù)完成辙浑。為體現(xiàn)此特性佃却,Java中規(guī)定:在類定義過程中,對于未定義構(gòu)造函數(shù)的類,默認會有一個無參數(shù)的構(gòu)造函數(shù)晤碘,作為所有類的基類,Object類自然要反映出此特性顾犹,在源碼中惕它,未給出Object類構(gòu)造函數(shù)定義,但實際上陋守,此構(gòu)造函數(shù)是存在的震贵。
當(dāng)然,并不是所有的類都是通過此種方式去構(gòu)建嗅义,也自然的屏歹,并不是所有的類構(gòu)造函數(shù)都是public。
private static native void registerNatives();
registerNatives函數(shù)前面有native關(guān)鍵字修飾之碗,Java中蝙眶,用native關(guān)鍵字修飾的函數(shù)表明該方法的實現(xiàn)并不是在Java中去完成,而是由C/C++去完成褪那,并被編譯成了.dll幽纷,由Java去調(diào)用。方法的具體實現(xiàn)體在dll文件中博敬,對于不同平臺友浸,其具體實現(xiàn)應(yīng)該有所不同。用native修飾偏窝,即表示操作系統(tǒng)收恢,需要提供此方法,Java本身需要使用祭往。具體到registerNatives()方法本身伦意,其主要作用是將C/C++中的方法映射到Java中的native方法,實現(xiàn)方法命名的解耦硼补。
protected Object clone()
Creates and returns a copy of this object.
Object類中的說明是:
protected Object clone() throws CloneNotSupportedException
這個方法比較特殊:
首先驮肉,使用這個方法的類必須實現(xiàn)java.lang.Cloneable接口,否則會拋出CloneNotSupportedException異常已骇。
Cloneable接口中不包含任何方法离钝,所以實現(xiàn)它時只要在類聲明中加上implements語句即可。
第二個比較特殊的地方在于這個方法是protected修飾的褪储,覆寫clone()方法的時候需要寫成public卵渴,才能讓類外部的代碼調(diào)用。
public final native Class<?> getClass();
getClass()也是一個native方法鲤竹,返回的是此Object對象的類對象/運行時類對象Class<?>奖恰。效果與Object.class相同。
首先解釋下"類對象"的概念:在Java中,類是是對具有一組相同特征或行為的實例的抽象并進行描述瑟啃,對象則是此類所描述的特征或行為的具體實例论泛。作為概念層次的類,其本身也具有某些共同的特性蛹屿,如都具有類名稱屁奏、由類加載器去加載,都具有包错负,具有父類坟瓢,屬性和方法等。于是犹撒,Java中有專門定義了一個類折联,Class,去描述其他類所具有的這些特性识颊,因此诚镰,從此角度去看,類本身也都是屬于Class類的對象祥款。為與經(jīng)常意義上的對象相區(qū)分清笨,在此稱之為"類對象"。
boolean equals(Object obj)
Indicates whether some other object is "equal to" this one.
“==”運算符判斷兩個引用是否指向同一個對象刃跛。==表示的是變量值完成相同(對于基礎(chǔ)類型抠艾,地址中存儲的是值,引用類型則存儲指向?qū)嶋H對象的地址)桨昙;
equals表示的是對象的內(nèi)容完全相同检号,此處的內(nèi)容多指對象的特征/屬性。
對于Object類的equals()方法來說蛙酪,它判斷調(diào)用equals()方法的引用于傳進來的引用是否一致谨敛,即這兩個引用是否指向的是同一個對象。
Object類中的equals()方法如下:
public boolean equals(Object obj) {
return (this == obj);
}
即Object類中的equals()方法等價于==滤否。
只有當(dāng)繼承Object的類覆寫(override)了equals()方法之后,繼承類實現(xiàn)了用equals()方法比較兩個對象是否相等最仑,才可以說equals()方法與==的不同藐俺。
equals()方法需要具有如下特點:
- 自反性(reflexive):任何非空引用x,x.equals(x)返回為true泥彤。
- 對稱性(symmetric):任何非空引用x和y欲芹,x.equals(y)返回true當(dāng)且僅當(dāng)y.equals(x)返回true。
- 傳遞性(transitive):任何非空引用x和y吟吝,如果x.equals(y)返回true菱父,并且y.equals(z)返回true,那么x.equals(z)返回true。
- 一致性(consistent):兩個非空引用x和y浙宜,x.equals(y)的多次調(diào)用應(yīng)該保持一致的結(jié)果官辽,(前提條件是在多次比較之間沒有修改x和y用于比較的相關(guān)信息)。
- 約定:對于任何非空引用x粟瞬,x.equals(null)應(yīng)該返回為false同仆。
- 并且覆寫equals()方法時,應(yīng)該同時覆寫hashCode()方法裙品,反之亦然俗批。
int hashCode()
Returns a hash code value for the object.
當(dāng)你覆寫(override)了equals()方法之后,必須也覆寫hashCode()方法市怎,反之亦然岁忘。
這個方法返回一個整型值(hash code value),如果兩個對象被equals()方法判斷為相等区匠,那么它們就應(yīng)該擁有同樣的hash code干像。
Object類的hashCode()方法為不同的對象返回不同的值,Object類的hashCode值表示的是對象的地址辱志。
hashCode的一般性契約(需要滿足的條件)如下:
1.在Java應(yīng)用的一次執(zhí)行過程中蝠筑,如果對象用于equals比較的信息沒有被修改,那么同一個對象多次調(diào)用hashCode()方法應(yīng)該返回同一個整型值揩懒。應(yīng)用的多次執(zhí)行中什乙,這個值不需要保持一致,即每次執(zhí)行都是保持著各自不同的值已球。
2.如果equals()判斷兩個對象相等臣镣,那么它們的hashCode()方法應(yīng)該返回同樣的值。
3.并沒有強制要求如果equals()判斷兩個對象不相等智亮,那么它們的hashCode()方法就應(yīng)該返回不同的值忆某。即,兩個對象用equals()方法比較返回false阔蛉,它們的hashCode可以相同也可以不同弃舒。但是,應(yīng)該意識到状原,為兩個不相等的對象產(chǎn)生兩個不同的hashCode可以改善哈希表的性能聋呢。
WHY?
其實,這主要體現(xiàn)在hashCode()方法的作用上颠区,其主要用于增強哈希表的性能削锰。
以集合類中,以Set為例毕莱,當(dāng)新加一個對象時器贩,需要判斷現(xiàn)有集合中是否已經(jīng)存在與此對象相等的對象颅夺,如果沒有hashCode()方法,需要將Set進行一次遍歷蛹稍,并逐一用equals()方法判斷兩個對象是否相等吧黄,此種算法時間復(fù)雜度為o(n)。通過借助于hasCode方法稳摄,先計算出即將新加入對象的哈希碼稚字,然后根據(jù)哈希算法計算出此對象的位置,直接判斷此位置上是否已有對象即可厦酬。(注:Set的底層用的是Map的原理實現(xiàn))
String toString()
Returns a string representation of the object.
當(dāng)打印引用胆描,如調(diào)用System.out.println()時,會自動調(diào)用對象的toString()方法仗阅,打印出引用所指的對象的toString()方法的返回值昌讲,因為每個類都直接或間接地繼承自O(shè)bject,因此每個類都有toString()方法减噪。
Object類中的toString()方法定義如下:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
wait(...) / notify() / notifyAll()
protected void finalize()
finalize方法主要與Java垃圾回收機制有關(guān)短绸。