Java父類Object的終極理解

Java父類Object的終極理解

長沙一度軟件培訓(xùn)      2022-05-03 00:49:01     28

Java父類Object的終極理解,一、定義(一)什么是object類1.Object類存儲(chǔ)在java.lang包中,使用的時(shí)候無需顯示導(dǎo)入,編譯時(shí)由編譯器自動(dòng)導(dǎo)入。是所有java類

課程價(jià)格 請(qǐng)咨詢

上課時(shí)段: 授課校區(qū):

詳細(xì)介紹

一、定義

(一)什么是object類

1.Object類存儲(chǔ)在java.lang包中,使用的時(shí)候無需顯示導(dǎo)入,編譯時(shí)由編譯器自動(dòng)導(dǎo)入。是所有java類(Object類除外)的終極父類(包括標(biāo)準(zhǔn)容器類,比如數(shù)組),不過接口不繼承Object類。

2.可以使用類型為Object的變量指向任意類型的對(duì)象。Object類的變量只能用作各種值的通用持有者,要對(duì)他們進(jìn)行任何專門的操作,都需要知道它們的原始類型并進(jìn)行類型轉(zhuǎn)換。

3.包含的函數(shù):

1)public Object();

2)protected Object clone()

3)boolean equals(Object obj)

4)protected void finalize()

5)Class<>getClass()

6)int hashCode()

7)void notify()

8)void notifyAll()

9)String toString()

10)void wait()

11)void wait(long timeout)

12)void wait(long timeout,int nanos)

二、用法

(一)常用函數(shù)解析

1.Object():默認(rèn)構(gòu)造方法。

1)Java中規(guī)定:在類定義過程中,對(duì)于未定義構(gòu)造函數(shù)的類,默認(rèn)會(huì)有一個(gè)無參數(shù)的構(gòu)造函數(shù),作為所有類的基類,Object類自然要反映出此特性,在源碼中,未給出Object類構(gòu)造函數(shù)定義,但實(shí)際上,此構(gòu)造函數(shù)是存在的。當(dāng)然,并不是所有的類都是通過此種方式去構(gòu)建,也自然的,并不是所有的類構(gòu)造函數(shù)都是public。

2.Clone():創(chuàng)建并返回此對(duì)象的一個(gè)副本。

1)clone()方法又是一個(gè)被聲明為native的方法,因此,我們知道了clone()方法并不是Java的原生方法,具體的實(shí)現(xiàn)是有C/C++完成的。clone英文翻譯為"克隆",其目的是創(chuàng)建并返回此對(duì)象的一個(gè)副本。clone函數(shù)返回的是一個(gè)引用,指向的是新的clone出來的對(duì)象,此對(duì)象與原對(duì)象分別占用不同的堆空間。

2)當(dāng)代碼執(zhí)行的時(shí)候,將會(huì)檢查調(diào)用對(duì)象的類(或者父類)是否實(shí)現(xiàn)了java.lang.Cloneable接口(Object類不實(shí)現(xiàn)Cloneable)。如果沒有實(shí)現(xiàn)這個(gè)接口,clone()將會(huì)拋出一個(gè)檢查異常()——java.lang.CloneNotSupportedException,如果實(shí)現(xiàn)了這個(gè)接口,clone()會(huì)創(chuàng)建一個(gè)新的對(duì)象,并將原來對(duì)象的內(nèi)容復(fù)制到新對(duì)象,最后返回這個(gè)新對(duì)象的引用。

3)淺克隆(也叫做淺拷貝)僅僅復(fù)制了這個(gè)對(duì)象本身的成員變量,該對(duì)象如果引用了其他對(duì)象的話,也不對(duì)其復(fù)制僅僅復(fù)制其引用(當(dāng)被復(fù)制的對(duì)象的引用類型變量?jī)?nèi)容發(fā)生變化時(shí)候,被復(fù)制的對(duì)象也會(huì)跟著變化)。

3.finalize():當(dāng)垃圾回收器確定不存在對(duì)該對(duì)象的更多引用時(shí),由對(duì)象的垃圾回收器調(diào)用此方法。

1)首先,Object中定義finalize方法表明Java中每一個(gè)對(duì)象都將具有finalize這種行為,其具體調(diào)用時(shí)機(jī)在:JVM準(zhǔn)備對(duì)此對(duì)形象所占用的內(nèi)存空間進(jìn)行垃圾回收前,將被調(diào)用。由此可以看出,此方法并不是由我們主動(dòng)去調(diào)用的(雖然可以主動(dòng)去調(diào)用,此時(shí)與其他自定義方法無異)。

4.equals()與hashCode():指示某個(gè)其他對(duì)象是否與此對(duì)象“相等”;返回該對(duì)象的哈希碼值。

1)重寫equals()方法必須重寫hashCode()方法。因?yàn)楫?dāng)僅僅重寫equals()方法改變了判斷對(duì)象相等條件,但是很多引用類型(例如hashMap等)判斷相等是通過hashCode()方法判斷key值是否相等,所以會(huì)導(dǎo)致意想的equals()要相等,但是hashCode()依舊是之前的邏輯導(dǎo)致不相等。

2)對(duì)象相等óequals()相等=>hashCode()相等;根據(jù)逆反定理:hashCode()不相等=>equals()不相等ó對(duì)象不相等

3)hashCode()相同的兩個(gè)對(duì)象不一定相等,換而言之不相等的兩個(gè)對(duì)象其hashCode()值可能相同。

5.getClass():返回一個(gè)對(duì)象的運(yùn)行時(shí)類。

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

6.toString:返回該對(duì)象的字符串表示。

1)在Object類中,它用于返回對(duì)象所屬類名和散列碼。

2)絕大多數(shù)的toString方法都遵循這個(gè)格式:類名[域值,域值,域值......]。

7.notify()、notifyAll():?jiǎn)拘言诖藢?duì)象監(jiān)視器上等待的單個(gè)/所有線程。

1)調(diào)用后,其所在線程不會(huì)立即釋放所持有的鎖,直到其所在同步代碼塊中的代碼執(zhí)行完畢,此時(shí)釋放鎖,因此,如果其同步代碼塊后還有代碼,其執(zhí)行則依賴于JVM的線程調(diào)度。

8.wait()、wait(long timeout)、wait(long timeout,int nanos):導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的notify()方法或notifyAll()方法、或者已超過某個(gè)實(shí)際時(shí)間量,、或者其他某個(gè)線程中斷當(dāng)前線程。

1)調(diào)用后當(dāng)前線程將立即阻塞,且釋放其所持有的同步代碼塊中的鎖,直到被喚醒或超時(shí)或打斷后且重新獲取到鎖后才能繼續(xù)執(zhí)行。

三、總結(jié)

1.既然比較兩個(gè)對(duì)象是否相等的唯一條件(也是沖要條件)是equals,那么為什么還要弄出一個(gè)hashCode(),并且進(jìn)行如此約定,弄得這么麻煩?

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

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

2.在程序執(zhí)行期間,只要equals方法的比較操作用到的信息沒有被修改,那么對(duì)這同一個(gè)對(duì)象調(diào)用多次,hashCode方法必須始終如一地返回同一個(gè)整數(shù)。

1)設(shè)計(jì)hashCode()時(shí)最重要的因素就是:無論何時(shí),對(duì)同一個(gè)對(duì)象調(diào)用hashCode()都應(yīng)該產(chǎn)生同樣的值。如果在講一個(gè)對(duì)象用put()添加進(jìn)HashMap時(shí)產(chǎn)生一個(gè)hashCdoe值,而用get()取出時(shí)卻產(chǎn)生了另一個(gè)hashCode值,那么就無法獲取該對(duì)象了。所以如果你的hashCode方法依賴于對(duì)象中易變的數(shù)據(jù),用戶就要當(dāng)心了,因?yàn)榇藬?shù)據(jù)發(fā)生變化時(shí),hashCode()方法就會(huì)生成一個(gè)不同的散列碼。

2)因此,在設(shè)計(jì)hashCode方法和equals方法的時(shí)候,如果對(duì)象中的數(shù)據(jù)易變,則最好在equals方法和hashCode方法中不要依賴于該字段。

3.大多數(shù)人認(rèn)為hashCode返回的就是對(duì)象的存儲(chǔ)地址,事實(shí)上這種看法是不全面的,確實(shí)有些JVM在實(shí)現(xiàn)時(shí)是直接返回對(duì)象的存儲(chǔ)地址,但是大多時(shí)候并不是這樣,只能說可能存儲(chǔ)地址有一定關(guān)聯(lián)。

Java Object類技術(shù)文檔:http://www.bjpowernode.com/tutorial_java_advance/606.html

以上就是長沙一度軟件培訓(xùn)java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Java父類Object的終極理解”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。

培訓(xùn)啦提醒您:交易時(shí)請(qǐng)核實(shí)對(duì)方資質(zhì),對(duì)于過大宣傳或承諾需謹(jǐn)慎!任何要求預(yù)付定金、匯款等方式均存在風(fēng)險(xiǎn),謹(jǐn)防上當(dāng)。