????????Object類位于類結(jié)構(gòu)樹的最頂端,所有的類都是它的直接或間接子類兔沃,因此所有的類都繼承了Object類的方法,我們可以在需要的時(shí)候覆蓋這些方法。下面是一些將會(huì)在本文中討論的Object類的方法:
protected Object clone() throws CloneNotSupportedException
創(chuàng)建并返回此對(duì)象的副本逻谦。
public boolean equals(Object obj)
判斷某個(gè)對(duì)象是否與這個(gè)對(duì)象“相等”。
protected void finalize() throws Throwable
當(dāng)垃圾回收器將對(duì)象從內(nèi)存中清理出去之前要做的清理工作陪蜻。
public final Class getClass()
返回對(duì)象所屬的類類型邦马。
public int hashCode()
返回對(duì)象的hash值。
public String toString()
返回對(duì)象的字符串表示形式囱皿。
??下面的notify勇婴,notifyAll和wait方法在同步獨(dú)立運(yùn)行的線程的活動(dòng)中扮演著不同的角色,本文不會(huì)去介紹它們嘱腥,有關(guān)這一部分的內(nèi)容將會(huì)在以后的文章中討論:
public final void notify()
public final void notifyAll()
public final void wait()
public final void wait(long timeout)
public final void wait(long timeout, int nanos)
一.equals方法
Object了類中的equals方法用于檢測(cè)一個(gè)對(duì)象是否等于另外一個(gè)對(duì)象耕渴。在Object類中,這個(gè)方法將會(huì)判斷兩個(gè)對(duì)象是否具有相同的引用齿兔。如果兩個(gè)對(duì)象具有相同的引用橱脸,它們一定是相等的。從這點(diǎn)上看分苇,將其作為默認(rèn)操作也是合乎情理的添诉。然而,對(duì)于大多數(shù)類來(lái)說(shuō)医寿,這種判斷并沒(méi)有什么意義栏赴。我們?cè)谂袛鄡蓚€(gè)對(duì)象是否相等時(shí),應(yīng)該比較它們的內(nèi)容靖秩,而不僅僅是判斷它們是不是同一個(gè)對(duì)象须眷。因此竖瘾,大多數(shù)情況下,當(dāng)我們需要使用equals方法時(shí)花颗,都應(yīng)該對(duì)它進(jìn)行重寫捕传。
為了演示,我們首先編寫一個(gè)Apple類:
publicclassApple{privateString color;privateintweight;publicvoidsetColor(String color){this.color = color;? ? }publicStringgetColor(){returncolor;? ? }publicvoidsetWeight(intweight){this.weight = weight;? ? }publicintgetWeight(){returnweight;? ? }}
??當(dāng)兩個(gè)蘋果的重量和顏色一樣時(shí)扩劝,我們就認(rèn)為它們是相等的庸论。因此,Apple類的equals方法可以這么寫:
publicbooleanequals(Object obj){if(obj ==null) {returnfalse;? ? }if(this== obj) {returntrue;? ? }if(this.getClass() != obj.getClass()) {returnfalse;? ? }? ? Apple apple = (Apple) obj;returnweight == apple.getWeight() && Objects.equals(color, apple.getColor());}
為了防備color為null的情況棒呛,上面的例子中使用了Objects.equals(Object a,Object b)方法聂示。如果a和b都是null,這個(gè)方法將會(huì)返回true条霜;如果其中只有一個(gè)參數(shù)為null催什,則返回false;如果a和b都不為null宰睡,則會(huì)返回a.equals(b)的結(jié)果蒲凶。
實(shí)際上,上面的equals還存在一定的問(wèn)題拆内。不過(guò)本文屬于基礎(chǔ)教程系列旋圆,因此不會(huì)深入講解這其中的問(wèn)題。有興趣的讀者可以查閱Java規(guī)范中對(duì)于equals方法的要求以及參考其他深入討論equals方法的文章麸恍。
二.hashCode方法
??hashCode方法的返回值是根據(jù)對(duì)象本身所計(jì)算出來(lái)的散列值(也稱哈希值)灵巧。如果兩個(gè)對(duì)象是相等的,那么對(duì)它們調(diào)用hashCode方法得到的返回值也應(yīng)該是相等的抹沪。如果重寫了equals方法刻肄,那么默認(rèn)的hashCode方法也不再適用。因此融欧,如果重寫了equals方法敏弃,則必須同時(shí)重寫hashCode方法。在重寫hashCode方法時(shí)噪馏,原則上只需要保證兩個(gè)相等的對(duì)象的散列值是相同的即可麦到。不過(guò)如何減少?zèng)_突以及編寫更高效的哈希函數(shù),可以參考其他文章或查閱計(jì)算機(jī)算法書中關(guān)于哈希的內(nèi)容欠肾。下面編寫了一個(gè)Apple類的hashCode方法作為示例:
publicinthashCode(){return7* (color ==null?0: color.hashCode()) +11* weight;}
三.clone方法
??如果一個(gè)類或它的某個(gè)超類實(shí)現(xiàn)了Cloneable接口瓶颠,那么就可以使用clone()方法從這個(gè)類的實(shí)例上創(chuàng)建一個(gè)副本。在調(diào)用clone()方法時(shí)刺桃,編譯器會(huì)檢查這個(gè)類是否實(shí)現(xiàn)了Cloneable接口粹淋。如果沒(méi)有,編譯器將會(huì)拋出一個(gè)CloneNotSupportedException異常。有關(guān)異常的內(nèi)容會(huì)在后面的文章中介紹廓啊,現(xiàn)在你只需要知道要覆蓋clone()方法欢搜,必須將它聲明為:
protectedObjectclone()throwsCloneNotSupportedException
或
publicObjectclone()throwsCloneNotSupportedException
如果調(diào)用clone方法的對(duì)象實(shí)現(xiàn)了Cloneable接口,則繼承自O(shè)bject類的clone()方法將會(huì)創(chuàng)建與原始對(duì)象相等的對(duì)象谴轮,使其具有與原始對(duì)象的相應(yīng)成員變量相同的值。因此吹埠,如果想要讓類可以clone第步,只需要將implements Cloneable添加到類的聲明中即可。
對(duì)于某些類缘琅,Objects類的clone方法可以正常工作粘都。但是,如果對(duì)象包含對(duì)外部對(duì)象的引用刷袍,則可能需要覆蓋clone方法翩隧。否則,即使克隆的對(duì)象與元對(duì)象不是一個(gè)對(duì)象呻纹,但它們內(nèi)部引用的還是相同的對(duì)象堆生。這樣一來(lái),對(duì)內(nèi)部對(duì)象所做的更改也會(huì)影響到另一個(gè)對(duì)象雷酪。如果需要克隆出一個(gè)完全與原對(duì)象隔離的新對(duì)象淑仆,則需要重寫clone方法,將每個(gè)內(nèi)部對(duì)象再拷貝一次哥力。
四.finalize方法
??finalize方法用于定義在回收對(duì)象前要執(zhí)行的清理工作蔗怠。Object類的finalize方法什么也沒(méi)做,只有一個(gè)空方法體吩跋,可以覆蓋finalize方法來(lái)定義清理行為寞射,例如釋放資源等。finalize方法不需要也不建議手動(dòng)調(diào)用锌钮,它會(huì)在垃圾回收器回收對(duì)象時(shí)自動(dòng)調(diào)用桥温。
五.toString方法
toString方法用于返回表示對(duì)象值的字符串。為每個(gè)類提供toString方法是一個(gè)良好的習(xí)慣轧粟。
下面是Object類的toString方法:
publicStringtoString(){returngetClass().getName() +"@"+ Integer.toHexString(hashCode());}
??可以看到策治,Object類的toString方法返回的是類名加對(duì)象的hashCode的十六進(jìn)制表示,中間使用符號(hào)@隔開兰吟。不過(guò)在打印對(duì)象的信息時(shí)通惫,這個(gè)方法的返回值并沒(méi)有什么意義。因此混蔼,建議在編寫的每一個(gè)類中都覆蓋toString方法履腋。例如為上面的Apple類編寫toString方法:
publicStringtoString(){returngetClass().getName() +"[color = "+ color +",weight = "+ weight +"]";}
六.getClass方法
Class類是一個(gè)表示類的信息的類。對(duì)對(duì)象調(diào)用getClass方法會(huì)返回一個(gè)Class類的實(shí)例,用來(lái)表示當(dāng)前對(duì)象所屬對(duì)象的信息遵湖。由于getClass方法是final的悔政,因此無(wú)法對(duì)它進(jìn)行重寫。
Class類提供了非常多的方法延旧,例如獲取類名的方法getSimpleName(),獲取父類的方法geuSuperClass()谋国,獲取實(shí)現(xiàn)的接口的方法getInterfaces()等。例如迁沫,下面的方法會(huì)打印出對(duì)象的類名:
voidprintClassName(Object obj){? ? System.out.println("The object's"+" class is "+ obj.getClass().getSimpleName());}
??有關(guān)Class的內(nèi)容會(huì)在后面有關(guān)反射的文章中進(jìn)行介紹芦瘾,這里只需要知道getClass方法的作用即可。