Java基礎(chǔ):Object類中的方法解析

概述

Object類是類層次結(jié)構(gòu)的根,Java中所有的類從根本上都繼承自這個(gè)類。Object類是Java中唯一沒(méi)有父類的類。其他所有的類,包括標(biāo)準(zhǔn)容器類,比如數(shù)組,都繼承了Object類中的方法。

Object類位于java.lang包中,java.lang包包含著Java最基礎(chǔ)和核心的類,在編譯時(shí)會(huì)自動(dòng)導(dǎo)入。Object類沒(méi)有定義屬性,一共有13個(gè)方法,具體的類定義結(jié)構(gòu)如下圖:


object_methods.jpg

Object類中的方法

Java中的每個(gè)類都具有定義在Object類中的這些方法。

構(gòu)造方法

public Object()
大部分情況下,Java中通過(guò)形如 new A(args..)形式創(chuàng)建一個(gè)屬于該類型的對(duì)象。其中A即是類名,A(args..)即此類定義中相對(duì)應(yīng)的構(gòu)造函數(shù)。通過(guò)此種形式創(chuàng)建的對(duì)象都是通過(guò)類中的構(gòu)造函數(shù)完成。為體現(xiàn)此特性,Java中規(guī)定:在類定義過(guò)程中,對(duì)于未定義構(gòu)造函數(shù)的類,默認(rèn)會(huì)有一個(gè)無(wú)參數(shù)的構(gòu)造函數(shù),作為所有類的基類,Object類自然要反映出此特性,在源碼中,未給出Object類構(gòu)造函數(shù)定義,但實(shí)際上,此構(gòu)造函數(shù)是存在的。

當(dāng)然,并不是所有的類都是通過(guò)此種方式去構(gòu)建,也自然的,并不是所有的類構(gòu)造函數(shù)都是public。

private static native void registerNatives();

registerNatives函數(shù)前面有native關(guān)鍵字修飾,Java中,用native關(guān)鍵字修飾的函數(shù)表明該方法的實(shí)現(xiàn)并不是在Java中去完成,而是由C/C++去完成,并被編譯成了.dll,由Java去調(diào)用。方法的具體實(shí)現(xiàn)體在dll文件中,對(duì)于不同平臺(tái),其具體實(shí)現(xiàn)應(yīng)該有所不同。用native修飾,即表示操作系統(tǒng),需要提供此方法,Java本身需要使用。具體到registerNatives()方法本身,其主要作用是將C/C++中的方法映射到Java中的native方法,實(shí)現(xiàn)方法命名的解耦。

protected Object clone()

Creates and returns a copy of this object.

Object類中的說(shuō)明是:

  protected Object clone() throws CloneNotSupportedException

這個(gè)方法比較特殊:
首先,使用這個(gè)方法的類必須實(shí)現(xiàn)java.lang.Cloneable接口,否則會(huì)拋出CloneNotSupportedException異常。
Cloneable接口中不包含任何方法,所以實(shí)現(xiàn)它時(shí)只要在類聲明中加上implements語(yǔ)句即可。

第二個(gè)比較特殊的地方在于這個(gè)方法是protected修飾的,覆寫clone()方法的時(shí)候需要寫成public,才能讓類外部的代碼調(diào)用。

public final native Class<?> getClass();

getClass()也是一個(gè)native方法,返回的是此Object對(duì)象的類對(duì)象/運(yùn)行時(shí)類對(duì)象Class<?>。效果與Object.class相同。

首先解釋下"類對(duì)象"的概念:在Java中,類是是對(duì)具有一組相同特征或行為的實(shí)例的抽象并進(jìn)行描述,對(duì)象則是此類所描述的特征或行為的具體實(shí)例。作為概念層次的類,其本身也具有某些共同的特性,如都具有類名稱、由類加載器去加載,都具有包,具有父類,屬性和方法等。于是,Java中有專門定義了一個(gè)類,Class,去描述其他類所具有的這些特性,因此,從此角度去看,類本身也都是屬于Class類的對(duì)象。為與經(jīng)常意義上的對(duì)象相區(qū)分,在此稱之為"類對(duì)象"。

boolean equals(Object obj)

Indicates whether some other object is "equal to" this one.
“==”運(yùn)算符判斷兩個(gè)引用是否指向同一個(gè)對(duì)象。==表示的是變量值完成相同(對(duì)于基礎(chǔ)類型,地址中存儲(chǔ)的是值,引用類型則存儲(chǔ)指向?qū)嶋H對(duì)象的地址);
equals表示的是對(duì)象的內(nèi)容完全相同,此處的內(nèi)容多指對(duì)象的特征/屬性。

對(duì)于Object類的equals()方法來(lái)說(shuō),它判斷調(diào)用equals()方法的引用于傳進(jìn)來(lái)的引用是否一致,即這兩個(gè)引用是否指向的是同一個(gè)對(duì)象。

Object類中的equals()方法如下:

public boolean equals(Object obj) {
    return (this == obj);
}

即Object類中的equals()方法等價(jià)于==。

只有當(dāng)繼承Object的類覆寫(override)了equals()方法之后,繼承類實(shí)現(xiàn)了用equals()方法比較兩個(gè)對(duì)象是否相等,才可以說(shuō)equals()方法與==的不同。

equals()方法需要具有如下特點(diǎn):

  • 自反性(reflexive):任何非空引用x,x.equals(x)返回為true。
  • 對(duì)稱性(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):兩個(gè)非空引用x和y,x.equals(y)的多次調(diào)用應(yīng)該保持一致的結(jié)果,(前提條件是在多次比較之間沒(méi)有修改x和y用于比較的相關(guān)信息)。
  • 約定:對(duì)于任何非空引用x,x.equals(null)應(yīng)該返回為false。
  • 并且覆寫equals()方法時(shí),應(yīng)該同時(shí)覆寫hashCode()方法,反之亦然。

int hashCode()

Returns a hash code value for the object.

當(dāng)你覆寫(override)了equals()方法之后,必須也覆寫hashCode()方法,反之亦然。

這個(gè)方法返回一個(gè)整型值(hash code value),如果兩個(gè)對(duì)象被equals()方法判斷為相等,那么它們就應(yīng)該擁有同樣的hash code。

Object類的hashCode()方法為不同的對(duì)象返回不同的值,Object類的hashCode值表示的是對(duì)象的地址。

hashCode的一般性契約(需要滿足的條件)如下:

1.在Java應(yīng)用的一次執(zhí)行過(guò)程中,如果對(duì)象用于equals比較的信息沒(méi)有被修改,那么同一個(gè)對(duì)象多次調(diào)用hashCode()方法應(yīng)該返回同一個(gè)整型值。應(yīng)用的多次執(zhí)行中,這個(gè)值不需要保持一致,即每次執(zhí)行都是保持著各自不同的值。
2.如果equals()判斷兩個(gè)對(duì)象相等,那么它們的hashCode()方法應(yīng)該返回同樣的值。
3.并沒(méi)有強(qiáng)制要求如果equals()判斷兩個(gè)對(duì)象不相等,那么它們的hashCode()方法就應(yīng)該返回不同的值。即,兩個(gè)對(duì)象用equals()方法比較返回false,它們的hashCode可以相同也可以不同。但是,應(yīng)該意識(shí)到,為兩個(gè)不相等的對(duì)象產(chǎn)生兩個(gè)不同的hashCode可以改善哈希表的性能。

WHY?
其實(shí),這主要體現(xiàn)在hashCode()方法的作用上,其主要用于增強(qiáng)哈希表的性能。

以集合類中,以Set為例,當(dāng)新加一個(gè)對(duì)象時(shí),需要判斷現(xiàn)有集合中是否已經(jīng)存在與此對(duì)象相等的對(duì)象,如果沒(méi)有hashCode()方法,需要將Set進(jìn)行一次遍歷,并逐一用equals()方法判斷兩個(gè)對(duì)象是否相等,此種算法時(shí)間復(fù)雜度為o(n)。通過(guò)借助于hasCode方法,先計(jì)算出即將新加入對(duì)象的哈希碼,然后根據(jù)哈希算法計(jì)算出此對(duì)象的位置,直接判斷此位置上是否已有對(duì)象即可。(注:Set的底層用的是Map的原理實(shí)現(xiàn))

String toString()

Returns a string representation of the object.
當(dāng)打印引用,如調(diào)用System.out.println()時(shí),會(huì)自動(dòng)調(diào)用對(duì)象的toString()方法,打印出引用所指的對(duì)象的toString()方法的返回值,因?yàn)槊總€(gè)類都直接或間接地繼承自O(shè)bject,因此每個(gè)類都有toString()方法。

Object類中的toString()方法定義如下:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

wait(...) / notify() / notifyAll()

protected void finalize()

finalize方法主要與Java垃圾回收機(jī)制有關(guān)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,697評(píng)論 18 399
  • (一)Java部分 1、列舉出JAVA中6個(gè)比較常用的包【天威誠(chéng)信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,265評(píng)論 0 62
  • 關(guān)于找茬兒小組 找茬兒小組,致力于打造一個(gè)深度互動(dòng)的專業(yè)寫作平臺(tái)。在這里,我們定期切磋,互評(píng)文章,交流經(jīng)驗(yàn),攻克寫...
    自我管理講師Jun閱讀 586評(píng)論 0 0
  • ——-魅力故鄉(xiāng)明山 我從遠(yuǎn)方歸來(lái) 相約冬日 如期而至 夕陽(yáng)下 你如含羞的新娘 對(duì)鏡梳妝 蜿蜒的山路 通向幕色深處 ...
    界輝閱讀 244評(píng)論 0 0
  • 〇、寫在前面 最近一直在使用Project軟件,使用中想到了很多。首先是這是一個(gè)功能強(qiáng)大的軟件,然后很多項(xiàng)目經(jīng)理都...
    易仁小生在進(jìn)化閱讀 28,410評(píng)論 1 19

友情鏈接更多精彩內(nèi)容