《effective java》讀書筆記2(對於所有物件都通用的方法)
前言:Object類的所有非final方法(equals,hashCode,toString,clone,finalize)被設計成被覆蓋的,但是它們有明確的通用約定,在覆蓋這些方法時需要遵守,否則會出現和其他類(HashMap,HashSet)配合使用的情況。
第8條:equals的通用約定
1.不需要覆蓋equals的情況:
》類的每個例項唯一,用Object的equals方法即可
》不關心類是否邏輯相等
》從超類繼承過來的equals方法也適合本身
》類是private或者public,別的地方無法訪問,或者確定equals方法不會被呼叫的時候。
2.需要覆蓋equals的清況:
》需要邏輯相等,超類中沒有實現equals方法
3.equals通用約定:
》自反,物件必須等於自身。例如set集合,如果不滿足自反,可能重複新增
》對稱,A.equals(B)且B.equals(A)。書中實現了一個忽略大小寫的CaseInsensitiveString類,讓其可以與普通String類相等,然而反過來String類的equals方法並不能與CaseInsensitiveString類邏輯相等,不滿足自反性
》傳遞,A.equals(B)且B.equals(C),那麼A.equals(C)
》一致,A.equals(B)那麼該句子恆成立
》引數非空,一般首先判斷引數是否instanceof,才進行型別轉換比較。
4.equals最佳實踐
》如果equals代價昂貴,最好加上==檢查是否為本身的引用
》instanceof防止型別錯誤或者null
》接著進行型別轉換
》比較關鍵域
//舉例
class A{
@Override
public boolean equals(Object o){
if(o==this) return true;
if(!(o instance A)) return false;
A a = (A)o;
...
}
}
5.注意事項
》覆蓋equals方法時總要覆蓋hashCode
》不要將上例子的equals(Object o)改為equals(A o),這樣看起來減少型別檢查,實際上修改後equals方法會變得很詭異,因為並沒有Override到Object類的equals方法。
第9條:覆蓋equals方法時總要覆蓋hashCode
因為像HashMap,HashTable,HashSet這些基於雜湊的集合需要同時用到equals和hashCode的方法,一般來說,邏輯相等的兩個物件要求hashCode值一樣,不相等的兩個物件hashCode值不要求一定不一樣,但是可以提高效能。
1.如何寫一個好的hashCode方法:
自定義雜湊函式 ,產生的雜湊值,使得邏輯相同的物件有相同的雜湊值(放入同一個桶中),邏輯不同的物件有不同的雜湊值(放入不同的桶中)。
結合equals方法的關鍵域,有如下步驟:
1.把一個非零的常數值,如17,儲存在一個名叫result的int變數中;
2.對於equals方法中的關鍵域產生int型別雜湊值:
boolean型別的域(如名叫f) 計算(f?1:0)
byte,char,short,int型別的域 計算 (int)f
long型別的域 計算 (int)(f^(f>>>32))
float型別的域 計算 Float.floatToIntBits(f)
double型別的域 計算 Double.doubleToLongBits(f)
引用型別的域 使用 引用型別的hashCode方法得到的雜湊值
陣列型別的域 把陣列中的每個元素當成一個關鍵域,計算出雜湊值。
3.對於每一個關鍵域計算出來的雜湊值 (如名叫c)
result = result * 31 + c;
最後放回這個result整數 就是計算出來的當前呼叫hashCode方法得到的雜湊值。
注意不要試圖從雜湊值的計算過程中排除一個關鍵域來提高雜湊值計算的效能。
第10條:始終覆蓋toString方法
主要是列印關鍵資訊方便除錯或日誌記錄
第11條:謹慎的覆蓋clone方法
Object類本身是沒有實現Cloneable介面的,並且clone方法是一個native方法。在預設的情況下,Object類中的clone是返回物件的逐域拷貝的,當然,這必須讓這個類實現了Cloneable介面,如果類不實現這個介面卻呼叫clone介面,就會丟擲CloneNotSupportedException。
所有實現了Cloneable介面的類都應該用一個公有的方法覆蓋clone,此方法首先呼叫super.clone,然後修正任何需要修正的域,例如:
@Override
public Stack clone() {
try {
Stack result = (Stack) super.clone();
result.elements = elements.clone();
return rsult;
} catch(CloneNotSupportedException e) {
throw new AssertionError();
}
第12條:考慮實現Comparable介面
一旦實現了該介面就可以和許多泛型演算法和支援該介面的集合進行協作。比如排序演算法,或者排序樹,這個用的多。
相關文章
- 《Effective Java 第二版》讀書筆記Java筆記
- 《Effective C++》讀書筆記C++筆記
- 《Effective-Ruby》讀書筆記筆記
- 讀書筆記2筆記
- 《Effective Objective-C 2.0》讀書/實戰筆記 一Object筆記
- [讀書筆記][effective C++]條款30-inline的原理筆記C++inline
- 《Effective DevOps》閱讀筆記 82dev筆記
- 《Effective DevOps》閱讀筆記 59dev筆記
- 《Effective DevOps》閱讀筆記 19dev筆記
- 讀書筆記(2)《微精通》筆記
- 《JavaScript 物件導向精要》 讀書筆記JavaScript物件筆記
- 《深度探索C++物件模型》讀書筆記C++物件模型筆記
- 《Head First Java》20201017讀書筆記Java筆記
- 《Head First Java》20200927讀書筆記Java筆記
- 《Head First Java》20201009讀書筆記Java筆記
- 關於Java中的類和物件筆記Java物件筆記
- 《HTTP/2 基礎教程》 讀書筆記HTTP筆記
- 《深入核心的敏捷開發》讀書筆記(2)敏捷筆記
- fluent python 讀書筆記 2–Python的序列型別2Python筆記型別
- Effective Objective-C 2.0讀書筆記(一)-如何減少標頭檔案的引入Object筆記
- 讀書筆記筆記
- 《讀書與做人》讀書筆記筆記
- 程式碼整潔之道--讀書筆記(2)筆記
- 《程式碼大全2》讀書筆記2(5-6)筆記
- 《Java程式設計思想》讀書筆記一Java程式設計筆記
- 讀書筆記-Java程式設計思想-03筆記Java程式設計
- 讀書筆記2-記憶體優化篇筆記記憶體優化
- Effective C++筆記C++筆記
- JVM讀書筆記之java記憶體結構JVM筆記Java記憶體
- webpackDemo讀書筆記Web筆記
- Vue讀書筆記Vue筆記
- 散文讀書筆記筆記
- Cucumber讀書筆記筆記
- HTTP 讀書筆記HTTP筆記
- postgres 讀書筆記筆記
- 讀書筆記3筆記
- java併發變成實戰讀書筆記(1,2章節)Java筆記
- 關於撲克牌的一些討論——《Fluent Python 2》讀書筆記Python筆記
- 《Haskell趣學指南》讀書筆記(2):Type And TypeclassHaskell筆記