標籤:style color 使用 strong 代碼 new
覆蓋equals時,遵守通用約定
對equal方法的覆蓋看起來很簡單,但是有許多情況是容易導致錯誤,最好的避免這些錯誤的辦法就是不覆蓋equals方法.
必須遵循的原則:自反性--對於任何非空的引用 x,有x.equals(x) 為true;對稱性--對於任何非空的引用x,y,如果x.equals(y) 為true,則必有y.equals(x) 為true;傳遞性--對於任何非空的引用x,y,z,如果x.equals(y) 為true且y.equals(z) 為true, 則必有x.equals(z) 為true;一致性--對於任何非空的引用x,y,只要equals的比較操作在對象中所用資訊沒被修改, 多次調用x.equals(y)會一致為TRUE或者一致為FALSE。
對於任何非空x,x.equals(null) 為FALSE。
實現高品質的equals方法的訣竅:
1、使用==操作符檢查是否為這個對象的引用。
2、使用instanceof檢查參數類型。 在繼承類或者介面調用時候,為了防止強制轉換錯誤,經常會先用instanceof判斷型別參數
3、把參數轉換成正確的類型。因為前面作了instanceof測試,所以強制轉換不會錯誤
4、對於該類中的關鍵域 ,檢查參數中的域與該對象中對於域是否匹配。
覆蓋equals時總是要覆蓋hashCode
只要對象的equals方法比較操作所用到的資訊沒被修改,那麼對這個對象調用多次,hashCode方法必須始終返回同一個整數。
如果兩個對象根據equals方法比較是相等的,那麼調用這兩個對象調用hashCode必須是同一個值
如果兩個對象的equals方法比較不相等,那麼調用這兩個對象hashCode不一定產生不同的整數。
相等的對象必須具有相等的散列碼
public final class Phone{
.....
@Override
public boolean equals(Object o){
....
}
}
假設你企圖將這個類與hashMap一起使用:
Map<Phnoe,String> map= new HashMap<Phnoe,String>();
map.put(new Phone(),"lily");
這時候,你可能期望map.get(new Phone())會返回一個 “lily”,但是實際返回為null
注意:這裡涉及兩個Phone執行個體,第一個被插入到map集合中,第二個執行個體和第一個相等,被用於擷取,由於Phone類沒有覆蓋hashCode方法,從而導致兩個相等的執行個體具有不同的散列碼,違反了hashCode方法約定。即put把一個Phone放入一個散列筒,但是get從另一個散列筒中拿取,所以為null;即便是正好從一個散列筒中操作,也會因為Hashmap‘的最佳化,可以緩衝相關聯的的散列碼。這樣get得到的也是null。