重寫Java中的equals方法介紹
Java中,只有8種基本類型不是對象,例如:4種整形類型(byte, short, int,long),2種浮點類型(flout, double),boolean, char不是對象,其他的所有類型,不論是對象數(shù)組,列表等都擴展了Object類.了解學(xué)習(xí)Object中方法的設(shè)計原理和實現(xiàn)方式有助于更好的學(xué)習(xí)理解java語言.下面,我們首先學(xué)習(xí)一下Object中的equals方法. 判斷兩個對象相等時,JVM首先查找兩個對象的hashCode, 如果兩者h(yuǎn)ashCode不同,則返回false;如果兩者的hashCode相同,則調(diào)用equals方法進(jìn)行比較.
Object中equals方法
Object中的equals方法用于檢測一個對象是否等于另外一個對象. Object類中,判斷兩個對象是否引用同一個對象實現(xiàn)equals方法,源碼如下:
public boolean equals(Object obj) { return (this == obj); }
實際處理中,若要比較兩個對象是否相等,一般需要重寫equals方法.
例1:雇員對象比較
如果兩個雇員對象的姓名, 薪水和雇傭一樣,就認(rèn)為它們相等.重寫equals方法如下:
public class Employee { private String name; private double salary; private Date hireDay; ... @Override public Boolean equals(Object obj) { // 如果為同一對象的不同引用,則相同 if (this == obj) { return true; } // 如果傳入的對象為空,則返回false if (obj == null) { return false; } // 如果兩者屬于不同的類型,不能相等 if (getClass() != obj.getClass()) { return false; } // 類型相同, 比較內(nèi)容是否相同 Employee other = (Employee) obj; return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay); }}
注意,比較通過Objects中靜態(tài)函數(shù)equals比較兩個對象是否相等.該方法源碼如下:
public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }
這樣,當(dāng)兩個對象都為null時,返回true,例如,兩個Employee對象的name都為null, 返回true; 如果第一個對象不為null,則調(diào)用a.equals(Object obj)方法
對象比較與繼承
如果隱式和顯式的對象所屬類型不一致,equals方法該如何處理呢?在例1中,如果兩個對象的類型不一致,直接返回false;多數(shù)程序員直接使用instanceof檢測:
if(!(obj instanceof Employee)) return false;
這樣做不但沒有解決繼承子類的錯誤,還可能引發(fā)其他的一些錯誤,例1中,采用強制類型轉(zhuǎn)換的方式.
要實現(xiàn)子類對象比較,先了解一下java規(guī)范中對equals方法的約束.
java規(guī)范中equals方法特征
自反性
對于任何非空引用x, x.equals(x) 返回true;
對稱性
對于任何引用x, y, 當(dāng)且僅當(dāng)y.equals(x) 返回true, x.equals(y)返回true;
傳遞性
對于任何引用x, y, z, 若x.equals(y)返回true, y.equals(z)返回true; 則 x.equals(z)返回true;
一致性
若x和y引用的對象沒有發(fā)生改變, 則反復(fù)調(diào)用x.equals(y)應(yīng)該返回同樣的結(jié)果.
對任意非空引用x, x.equals(null) 返回false;
下面可以通過兩個不同的情況看待這個問題:
如果子類能夠擁有自己的相等概念, 則對稱性需求強制采用getClass進(jìn)行檢測
如果由超類決定相等的概念, 那么就用instanceof進(jìn)行檢測,這樣可以在不用子類的對象之間進(jìn)行相等的比較
注釋:
在標(biāo)準(zhǔn)的java庫中包含150多個equals方法的實現(xiàn),包括instanceof檢測, 調(diào)用getClass檢測, 捕獲ClassCastException檢測或者什么都不做. 在java.sql.TimeStamp實現(xiàn)人員指出, Timestamp類繼承Date類,而后者的equals方法使用了一個instanceof檢測,這樣重寫equals方法時,就無法同時做到對稱性.
在由超類決定相等時,可以考慮final關(guān)鍵字修改比較函數(shù),若考慮到子類equals方法靈活性,可以不加修飾,例如AbstractSet.equals方法,應(yīng)該申明為final, 這樣就可以比較子類HashSet和TreeSet, 但是考慮到子類的靈活性,沒有添加任何修飾.
編寫equals方法的建議:
顯示參數(shù)命名為otherObject, 稍后轉(zhuǎn)化成other變量
public boolean equals(Object otherObject)
檢測this和otherObject是否是同一個對象的引用,是,返回true;
if(this==otherObject){ return true; }
檢測otherObject是否為null, 是, 返回false;
if(otherObject == null){ return false; }
比較this和otherObject是否屬于同一個類. 如果equals的語義在每個子類中有所改變,就使用getClass檢測:
if(getClass() != otherObject.getClass()){ return false; }
如果所以子類語義相同,使用instanceof檢測:
if(!(otherObject instanceof Employee)){ return false; }
將otherObject轉(zhuǎn)化為相對應(yīng)的類型變量other
Employee other = (Employee)otherObject;
對所需要的比較的數(shù)據(jù)域進(jìn)行比較. 如果是基本數(shù)據(jù)類型,使用a==b比較; 如果是對象比較,調(diào)用Objects.equals(a, b)進(jìn)行比較
return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
整個流程可以參照例1;
常見equals方法實現(xiàn)錯誤
public class Employee { public Boolean equals(Employee other) { return Objects.equals(name, other.name) && salary ==other.salary && Objects.equals(hireDay, other.hireDay); }
總結(jié)
以上就是本文關(guān)于重寫Java中的equals方法介紹的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:淺談java中==以及equals方法的用法、java定時器timer的使用方法代碼示例等,有什么問題可以隨時留言,小編會及時回復(fù)大家的。感謝朋友們對本站的支持!
相關(guān)文章
Spring中byName和byType的區(qū)別及說明
這篇文章主要介紹了Spring中byName和byType的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12使用Spring Security集成手機驗證碼登錄功能實現(xiàn)
本文詳細(xì)介紹了如何利用SpringSecurity來實現(xiàn)手機驗證碼的注冊和登錄功能,在登錄過程中,同樣需通過驗證碼進(jìn)行驗證,文章還提供了相關(guān)的代碼實現(xiàn)2024-10-10Netty分布式ByteBuf使用subPage級別內(nèi)存分配剖析
這篇文章主要為大家介紹了Netty分布式ByteBuf使用subPage級別內(nèi)存分配剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03SpringBoot如何優(yōu)雅地使用Swagger2
這篇文章主要介紹了SpringBoot如何優(yōu)雅地使用Swagger2,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07