一、equals方法
1.一、簡介
equals()方法,定義在Object類中,源碼以下:html
public boolean equals(Object obj) {
return (this == obj);
}
也就是說,在Object類中,比較的是兩個對象的引用是否相同。
當咱們建立一個新的類而沒有覆蓋equals方法時,調用equals方法即比較兩個對象的引用是否相同,此時與使用「==」比較是同樣的。java
1.二、equals與==
參考:淺談Java中的equals和==測試
String類對equals方法進行了重寫,用來比較指向的字符串對象所存儲的字符串是否相等。其餘的一些類諸如Double,Date,Integer等,都對equals方法進行了重寫用來比較指向的對象所存儲的內容是否相等。flex
總結來講:ui
- 對於==,若是做用於基本數據類型的變量,則直接比較其存儲的 「值」是否相等;若是做用於引用類型的變量,則比較的是所指向的對象的地址
- 對於equals方法(注意:equals方法不能做用於基本數據類型的變量),若是沒有對equals方法進行重寫,則比較的是引用類型的變量所指向的對象的地址;諸如String、Date等類對equals方法進行了重寫的話,比較的是所指向的對象的內容。
二、不須要覆蓋equals方法
當有以下條件時,不須要覆蓋equals方法:this
- 類的每一個實例本質上都是惟一的。
- 不關心類是否提供了「邏輯相等(logical equality)」的測試功能。
- 超類已經覆蓋了equals,從超類繼承過來的行爲對於子類也是適合的。
- 類是私有的或是包級私有的,能夠肯定它的equals方法永遠不會被調用。
三、覆蓋equals方法
3.一、何時該覆蓋
若是類具備本身特有的「邏輯相等」概念(不一樣於對象等同的概念),並且超類尚未覆蓋equals以實現指望的行爲,這時就須要覆蓋equals方法。
這一般屬於「值類(value class)」的情形。值類僅僅是一個表示值的類,例如Ingeter或Date,在利用equals方法來比較值對象的引用時,但願知道它們在邏輯上是否相等,而不是想了解它們是否指向同一個對象。.net
3.二、覆蓋時遵照約定
等價關係(equivalence relation):code
- 自反性(reflexive):對於任何非null的引用值x,x.equals(x)必須返回true。
- 對稱性(symmetric):對於任何非null的引用值x和y,當且僅當y.equals(x)返回true時,x.equals(y)必須返回true。
- 傳遞性(transitive):對於任何非null的引用值x,y和z,若是x.equals(y)返回true,且y.equals(z)返回true,那麼x.equals(z)也必須返回true。
- 一致性(consistent):對於任何非null的引用值x和y,只有equals的比較操做在對象中所用的信息沒有被修改,屢次調用x.equals(y)總會一致地返回相同的結果。
- 非空性(Non-nullity):對於任何非null的引用值x,x.equals(null)必須返回false。
四、實現高質量equals
- 使用「==」操做符檢查「參數是否爲這個對象的引用」。
- 使用instanceof操做符檢查「參數是否爲正確的類型」。
- 把參數轉換成正確的類型。
- 對於該類中的每一個「關鍵(significant)」域,檢查參數中的域是否與該對象中對應的域相匹配。
- 當你編寫完成了equals方法以後,應該問本身三個問題:它是否對稱的、傳遞的、一致的?
五、告誡
- 覆蓋equals時總要覆蓋hashCode
- 不要企圖讓equals方法過於智能
- 不要將equals聲明中的Object對象替換爲其餘的類型。
六、參考