超類(lèi)Object中有這個(gè)equals()方法,該方法主要用于比較兩個(gè)對(duì)象是否相等。該方法的源碼如下:
[java] view plain copy我們知道所有的對(duì)象都擁有標(biāo)識(shí)(內(nèi)存地址)和狀態(tài)(數(shù)據(jù)),同時(shí)“==”比較兩個(gè)對(duì)象的的內(nèi)存地址,所以說(shuō)使用Object的equals()方法是比較兩個(gè)對(duì)象的內(nèi)存地址是否相等,即若object1.equals(object2)為true,則表示equals1和equals2實(shí)際上是引用同一個(gè)對(duì)象。雖然有時(shí)候Object的equals()方法可以滿(mǎn)足我們一些基本的要求,但是我們必須要清楚我們很大部分時(shí)間都是進(jìn)行兩個(gè)對(duì)象的比較,這個(gè)時(shí)候Object的equals()方法就不可以了,實(shí)際上JDk中,String、Math等封裝類(lèi)都對(duì)equals()方法進(jìn)行了重寫(xiě)。下面是String的equals()方法:
[java] view%20plain copy對(duì)于這個(gè)代碼段:if%20(v1[i++]%20!=%20v2[j++])return%20false;我們可以非常清晰的看到String的equals()方法是進(jìn)行內(nèi)容比較,而不是引用比較。至于其他的封裝類(lèi)都差不多。
在Java規(guī)范中,它對(duì)equals()方法的使用必須要遵循如下幾個(gè)規(guī)則:
equals%20方法在非空對(duì)象引用上實(shí)現(xiàn)相等關(guān)系:
1、自反性:對(duì)于任何非空引用值%20x,x.equals(x)%20都應(yīng)返回%20true。
2、對(duì)稱(chēng)性:對(duì)于任何非空引用值%20x%20和%20y,當(dāng)且僅當(dāng)%20y.equals(x)%20返回%20true%20時(shí),x.equals(y)%20才應(yīng)返回%20true。
3、傳遞性:對(duì)于任何非空引用值%20x、y%20和%20z,如果%20x.equals(y)%20返回%20true,并且%20y.equals(z)%20返回%20true,那么%20x.equals(z)%20應(yīng)返回%20true。
4、一致性:對(duì)于任何非空引用值%20x%20和%20y,多次調(diào)用%20x.equals(y)%20始終返回%20true%20或始終返回%20false,前提是對(duì)象上%20equals%20比較中所用的信息沒(méi)有被修改。
5、 對(duì)于任何非空引用值%20x,x.equals(null)%20都應(yīng)返回%20false。
對(duì)于上面幾個(gè)規(guī)則,我們?cè)谑褂玫倪^(guò)程中最好遵守,否則會(huì)出現(xiàn)意想不到的錯(cuò)誤。
在java中進(jìn)行比較,我們需要根據(jù)比較的類(lèi)型來(lái)選擇合適的比較方式:
1) 對(duì)象域,使用equals方法%20。 2) 類(lèi)型安全的枚舉,使用equals或==%20。 3) 可能為null的對(duì)象域%20:%20使用%20==%20和%20equals%20。 4) 數(shù)組域%20:%20使用%20Arrays.equals%20。 5) 除float和double外的原始數(shù)據(jù)類(lèi)型%20:%20使用%20==%20。 6) float類(lèi)型:%20使用Float.foatToIntBits轉(zhuǎn)換成int類(lèi)型,然后使用==。 7) double類(lèi)型:%20使用Double.doubleToLongBit轉(zhuǎn)換成long類(lèi)型,然后使用==。
至于6)、7)為什么需要進(jìn)行轉(zhuǎn)換,我們可以參考他們相應(yīng)封裝類(lèi)的equals()方法,下面的是Float類(lèi)的:
[java] view%20plain copy原因嘛,里面提到了兩點(diǎn):
[java] view%20plain copy子類(lèi):Employee
[java] view%20plain copy上面父類(lèi)Person和子類(lèi)Employee都重寫(xiě)了equals(),不過(guò)Employee比父類(lèi)多了一個(gè)id屬性。測(cè)試程序如下:
[java] view%20plain copy上面定義了兩個(gè)員工和一個(gè)普通人,雖然他們同名,但是他們肯定不是同一人,所以按理來(lái)說(shuō)輸出結(jié)果應(yīng)該全部都是false,但是事與愿違,結(jié)果是:true、true、false。
對(duì)于那e1!=e2我們非常容易理解,因?yàn)樗麄儾粌H需要比較name,還需要比較id。但是p1即等于e1也等于e2,這是非常奇怪的,因?yàn)閑1、e2明明是兩個(gè)不同的類(lèi),但為什么會(huì)出現(xiàn)這個(gè)情況?首先p1.equals(e1),是調(diào)用p1的equals方法,該方法使用instanceof關(guān)鍵字來(lái)檢查e1是否為Person類(lèi),這里我們?cè)倏纯磇nstanceof:判斷其左邊對(duì)象是否為其右邊類(lèi)的實(shí)例,也可以用來(lái)判斷繼承中的子類(lèi)的實(shí)例是否為父類(lèi)的實(shí)現(xiàn)。他們兩者存在繼承關(guān)系,肯定會(huì)返回true了,而兩者name又相同,所以結(jié)果肯定是true。
所以出現(xiàn)上面的情況就是使用了關(guān)鍵字instanceof,這是非常容易“專(zhuān)空子”的。故在覆寫(xiě)equals時(shí)推薦使用getClass進(jìn)行類(lèi)型判斷。而不是使用instanceof。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注