一、覆蓋equals方法需謹慎,可能會致使嚴重後果java
二、覆蓋equals 方法指望你知足:sql
(1)類的每一個實例本質上都是惟一的數組
- 表明活動實體而不是值得類確實如此
- Object 的equals 本質調用的是 ==
- 對於像String 類就是作值判斷,和這裏要求的惟一不是一種狀況
(2)不關心類是否提供了」邏輯相等「的測試功能ide
- 在類的每一個實例都與自身相等狀況下,從Object繼承已經足夠了
(3)超類已經覆蓋了equals 方法,從超類繼承的equals方法對於子類也是合適的性能
- Set實現都從AbstractSet 繼承equals 實現,Map、List 也是
(4)類是私有的 或包級私有的 能夠保證equals 方法永遠不會被調用測試
- 未聲明(包級私有)、 public、protected、private
- 類的訪問權限:
三、何時須要覆蓋equals 方法:優化
- 類具備本身獨有的邏輯相等概念(不一樣於對象等同概念)
- 父類又沒有實現指望的 equals 行爲
- 一般指 」值類「 如String、Integer、Date等
- 覆蓋equals 方法,還須要使類的實例能夠作map的key ,集合(set)的相關要求
- 上述map的key 要求不相等,集合(set)不能有重複項:都是equals判斷的
- 實際上,上述先用hashcode判斷,而後再equals 比較,提升效率
四、實例受控<1條>確保每一個值最多存在一個對象的狀況,不用覆蓋.net
五、覆蓋equals 方法,遵照通用約定:code
(1)自反性:任何非null 值,x.equals(x) 必須返回true對象
(2)對稱性:任何非null 值,x.equals(y)==true,則必須知足y.equals(x)==true
- 以下紅框所示,該類實例和String 實例比較時
- caseIns.equals(str)==true,可是 str.equals(caseIns)==false
(3)傳遞性:任何非null 值,x.equals(y)==true,x.equals(z)==true,則必須知足x.equals(y)==true
- 咱們沒法擴展可實例化類的同時,既增長組件,又保留equals 方法的約定
ColorPoint 繼承自Point ,多了一個color 屬性
覆蓋equals 方法1:
- 該方法問題在於,沒法比較 p.equals(cp)==true, cp.equals(p)==false 沒有實現傳遞性
覆蓋equals 方法2:
- instanceof具備傳遞性(實例 的類、父類、實現接口 都知足)
- 實現了對稱性,沒有實現傳遞性
好比:
- p1.equals(p2)==true,p2.equals(p3)==true, 可是:p1.equals(p3)==false
這裏可使用組合的方式知足上述需求:
- java.sql.Timestamp 擴展了java.util.Date 增長了域,不知足equals 約定,是很差的案例
可是,咱們能夠在抽象類的子類中添加新的組件、而且不違反equals 約定
(4)一致性;任何非null 值,只要equals 比較所用信息沒變,屢次調用 都能獲得 x.equals(y)==true
- equals 方法永遠不要依賴不可靠資源
- java.net.URL的equals 方法依賴於主機IP地址的比較,IP地址是不靠譜資源,由於IP地址會變
(5)非空性:對於任何非null 值,必有 x.equals(null)==false
- 判空沒必要要緣由以下,即類型判斷的存在
- 若是 o 是空,instanceof 返回的都是false,因此不須要單獨判空
有許多類,包括全部集合類,都依賴於傳遞給他們的equals 方法是否聽從約定
六、高質量equals 方法實現訣竅:
(1)使用== 檢查 "參數是否爲這個對象的引用"
(2)使用instanceof 檢查 」參數是否爲正確的類型「
(3)把參數轉換成正確的類型
(4)檢查該類中的每一個」關鍵「域,檢查參數中的域是否與該對象中對應的域相匹配
- 若是是接口,必須經過接口方法訪問每個域
- 類的話,根據可訪問性訪問
- 對於非(float、double)浮點的基本類型,可採用== 比較
- 對於浮點數,可採用Float.compare、Double.compare比較
- 浮點數特殊處理是必要的,由於存在Float.NaN、-0.0f等特殊常量(Double相似)
- 數組域,對每一個元素比較;或者採用Arrays.equals方法比較
- 有些引用域null 是合法的,採用下述比較:
- 域的比較比等同比較複雜得多,可保存」範式「 以儘可能使用低成本精確比較
域的比較順序也會影響性能
- 優先比較開銷最低的域、最可能不一致的域,同時知足兩者
(5)完成equals 方法,再三確認是否 對稱、一致、傳遞
- 還有 自反性、非空性,這倆通常自動知足
- 覆蓋equals 時,總要覆蓋hashcode<9條>
- 不要企圖讓equals 過於智能 不要過分準求各類等價關係
如:File 類的指向同一個文件的各類符號連接相等,File 沒有那麼作
- 不要將equals 參數中的Object 替換成其餘類型
- 以下所述,這樣並無覆蓋Object的equals 方法,僅僅重載了equals 方法
- 這樣在某些時候提高性能,但複雜度加大,得不償失