Methods Common to All Objects

 

item 7:當(dāng)你覆蓋equals方法的時(shí)候一定要遵守general contact

 

   覆蓋equals的時(shí)候一定要加倍的小心,其實(shí)最好的辦法就是不覆蓋這個(gè)方法。比如在下面的情況下就可以不覆蓋

   1這個(gè)類的每個(gè)實(shí)例都是唯一的,例如Thread

   2 如果你不關(guān)心這個(gè)類是否該提供一個(gè)測試邏輯相等的方法

   3超類已經(jīng)覆蓋了equals方法,并且它合適子類使用

   4如果這個(gè)類是private或者是package-private的,并且你確信他不會(huì)被調(diào)用

 

   但是當(dāng)我們要為這個(gè)類提供區(qū)分邏輯相等和引用相等的方法的時(shí)候,我們就必須要覆蓋這個(gè)方法了。例如String類,Date類等,覆蓋的時(shí)候我們一定要遵從general contact,說白了就是一個(gè)合同。合同的主要內(nèi)容是

   1x.equals(x)必須返回true

   2x.equalsy)當(dāng)且僅當(dāng)y.equals(x)返回true的時(shí)候返回true

   3x.equals(y)返回truey.equals(z)返回true,那么x.equals(z)必須返回true

   4.如果沒有任何修改得話 那么多次調(diào)用x.equals(y)的返回值應(yīng)該不變

   5.任何時(shí)候非空的對象x,x.equals(null)必須返回false

下面是作者的建議如何正確的覆蓋equals方法

1.  ==檢查是否參數(shù)就是這個(gè)對象的引用

2.  instanceof判斷參數(shù)的類型是否正確

3.  把參數(shù)轉(zhuǎn)換成合適的類型

4.  比較類的字段是不是匹配

例如:

public boolean equals(Object o)

{

       if(o== this) return true;

       if(!(o instanceof xxxx) return false;

       xxx in = (xxx)o;

       return ……..

}

最后一點(diǎn)要注意的時(shí)候不要提供這樣的方法public boolean equals(MyClass o)這樣是重載并不是覆蓋Objectequals方法

item 8 :當(dāng)你覆蓋equals的時(shí)候必須覆蓋hashCode方法

    這點(diǎn)必須切忌,不然在你和hash-based集合打交道的時(shí)候,錯(cuò)誤就會(huì)出現(xiàn)了。關(guān)鍵問題在于一定要滿足相等的對象必須要有相等的hashCode。如果你在PhoneNumber類中覆蓋了equals方法,但是沒有覆蓋hashCode方法,那么當(dāng)你做如下操作的時(shí)候就會(huì)出現(xiàn)問題了。

Map m = new HashMap();

m.put(new PhoneNumber(408,863,3334),”ming”)
當(dāng)你調(diào)用m.get(new PhoneNumber(408,863,3334))的時(shí)候你希望得到ming但是你卻得到了null,為什么呢因?yàn)樵谡麄€(gè)過程中有兩個(gè)PhoneNumber的實(shí)例,一個(gè)是put一個(gè)是get,但是他們兩個(gè)邏輯相等的實(shí)例卻得到不同的hashCode那么怎么可以取得以前存入的ming呢。

 

Item 9:永遠(yuǎn)覆蓋toString方法

    在ObjecttoString方法返回的形式是Class的類型加上@加上16進(jìn)制的hashcode。你最好在自己的類中提供toString方法更好的表述實(shí)例的信息,不然別人怎么看得明白呢。

 

Item 10:覆蓋clone()方法的時(shí)候一定要小心

    一個(gè)對象要想被Clone,那么要實(shí)現(xiàn)Clone()接口,這個(gè)接口沒有定義任何的方法,但是如果你不實(shí)現(xiàn)這個(gè)接口的話,調(diào)用clone方法的時(shí)候會(huì)出現(xiàn)CloneNotSupportedException,這就是作者叫做mixin的接口類型。通常clone()方法可以這樣覆蓋

public Object clone()

{

try
{

              return super.clone();

}

catch(CloneNotSupportedException e)
{}

}

但是當(dāng)你要clone的類里面含有可修改的引用字段的時(shí)候,那么你一定要把整個(gè)類的藍(lán)圖進(jìn)行復(fù)制,如果對你clone得到的對象進(jìn)行修改的時(shí)候還會(huì)影響到原來的實(shí)例,那么這是不可取的。所以應(yīng)該這樣clone()

public Object clone() throws CloneNotSupportedException

{

       Stack Result  = (Stack)super.clone();

       Result.elements = (Object[])elements.clone();

       Return result;

}

其中elementsstack類中可修改的引用字段,注意如果elementsfinal的話我們就無能為力了,因?yàn)椴荒芙o他重新賦值了.其實(shí)如果不是必須的話,根本就不用它最好。

 

Item 11:考慮適當(dāng)?shù)臅r(shí)候覆蓋Comparable接口

     Thinking in java上說的更清楚,這里不多少了。