覆蓋equals時請遵守通用約定

第8條:覆蓋equals時請遵守通用約定


1. 前言

覆蓋equals方法看似很簡單邦尊,但是有許多覆蓋方法或?qū)е洛e誤穗酥,避免這些錯誤最直接的方法就是不覆蓋equals立由,這樣后裸,沒有對象就只與自己相等。

2. 不需要覆蓋equals方法的情況有哪些?

(1)類的每一個實體本質(zhì)上都是唯一的轿衔。比如Thread類沉迹,每一個實體都是唯一的,所以不需要覆蓋equals方法害驹。

(2)不關(guān)心類是否提供了“邏輯相等”的測試功能鞭呕。·

(3)父類已經(jīng)覆蓋了equals方法,并且在子類中這些方法同樣適用宛官。

(4)類是私有的或是包級私有的葫松,可以確定equals方法永遠(yuǎn)不會被調(diào)用。其實這種情況我們還是應(yīng)該覆蓋equals的方法的底洗,將equals方法設(shè)置成不可訪問的腋么。像下面這樣:

@Override
public boolean equals(Object o) {
    throw new AssertionError();
}

3. 需要覆蓋equals方法的情況

一般來說,“值類”都是需要覆蓋equals方法的亥揖。
什么類屬于“值類”珊擂?
對于那些只關(guān)心內(nèi)容,不關(guān)心是否指向同一片內(nèi)存空間的類费变,都屬于“值類”摧扇。
注意:有一種“值類”不需要覆蓋equals方法,那就是單例挚歧。也就是說扛稽,如果一個類,它又是單例又是“值類”的話滑负,它就不需要覆蓋equals方法在张。

4. 在覆蓋equals方法時我們需要遵行的規(guī)范

(1)自反性:
即對于一個非空對象x,x.equals(x)必須返回true橙困。

(2)對稱性:
即對于非空的對象x瞧掺、y,如果x.equals(y)返回true的話凡傅,則y.equals(x)則必須返回true。

(3)傳遞性:
即對于非空的對象x肠缔、y夏跷、z,如果x.equals(y)返回true明未,y.equals(z)返回true槽华,則x.eqauls(z)則必須返回true。

(4)一致性:
即對于非空對象x趟妥,y猫态,只要equals方法的中比較的字段沒有被修改,那么x.equals(y)不管執(zhí)行多少次都是返回true,或都是返回false亲雪。

(5)和null相比必須返回false:
即對于非空對象x勇凭,x.equals(null)必須返回false;

5. 實現(xiàn)高質(zhì)量equals方法的訣竅

(1)用==操作符來檢查“參數(shù)是否是這個對象的引用”义辕。如果是虾标,則返回true。
這樣做是為了提高性能灌砖。

(2)使用instanceof操作符來檢查“參數(shù)是否為真確類型”璧函。如果不是,則返回false基显。
“正確類型”一般指的是equals方法所在的類蘸吓。有些情況是指該類所實現(xiàn)的某個接口。

(3)把參數(shù)轉(zhuǎn)化為真確的類型撩幽。
在被instanceof檢測過后库继,我們就將Object強行轉(zhuǎn)換成上面所提到的“正確的類型”,instanceof保證了我們轉(zhuǎn)換的真確性摸航。

(4)對于該類中的每個關(guān)鍵域(字段)制跟,檢查參數(shù)中的域是否與該對象中所對應(yīng)的域想匹配。
強轉(zhuǎn)之后酱虎,就可以開始匹配兩個對象中的字段了雨膨。如果匹配成功就可以返回true,如果“正確的類型”是一個接口读串,那么需要接口提供方法來訪問這些字段聊记,如果是個類的話,那就不用說了恢暖。
字段匹配技巧:

a排监、如果是非float和double類型的基本數(shù)據(jù)類型,那么直接使用==符號杰捂。

b舆床、如果是float和double,則使用Float.compare和Double.compare方法嫁佳。

c挨队、其他類型(也就是那些需要new出對象的類)則調(diào)用他們自身的equals方法。有些字段可能被允許為空蒿往,所以要進(jìn)行判斷盛垦,如下:

field == null ?  o.field == null : filed.equal(0.field);

d、數(shù)組的話需要遍歷每一個元素進(jìn)行匹配瓤漏,匹配的時候參考上面的三條方法腾夯。

6. 覆蓋equals方法的時候我們還需要注意的地方

(1) 覆蓋equals的時候總是要覆蓋hashCode方法颊埃。(為什么覆蓋和怎么覆蓋會在下一篇文章講)
(2) 不要企圖讓equals方法過于智能。只是匹配對象的類型和對象中的各個參數(shù)的話很容易做到蝶俱,并且一般不會違反上面提到的規(guī)范班利。如果你過度的去尋求各種等價關(guān)系,那么上面的約定將很難遵守跷乐。
(4)覆蓋equals方法的時候請在方法前面加@Override注解肥败。

本文到此結(jié)束

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市愕提,隨后出現(xiàn)的幾起案子馒稍,更是在濱河造成了極大的恐慌,老刑警劉巖浅侨,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纽谒,死亡現(xiàn)場離奇詭異,居然都是意外死亡如输,警方通過查閱死者的電腦和手機鼓黔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來不见,“玉大人澳化,你說我怎么就攤上這事∥人保” “怎么了缎谷?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長灶似。 經(jīng)常有香客問我列林,道長,這世上最難降的妖魔是什么酪惭? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任希痴,我火速辦了婚禮,結(jié)果婚禮上春感,老公的妹妹穿的比我還像新娘砌创。我一直安慰自己,他們只是感情好鲫懒,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布纺铭。 她就那樣靜靜地躺著,像睡著了一般刀疙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扫倡,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天谦秧,我揣著相機與錄音竟纳,去河邊找鬼。 笑死疚鲤,一個胖子當(dāng)著我的面吹牛锥累,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播集歇,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼桶略,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诲宇?” 一聲冷哼從身側(cè)響起际歼,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎姑蓝,沒想到半個月后鹅心,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡纺荧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年旭愧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宙暇。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡输枯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出占贫,到底是詐尸還是另有隱情桃熄,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布靶剑,位于F島的核電站蜻拨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏桩引。R本人自食惡果不足惜缎讼,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坑匠。 院中可真熱鬧血崭,春花似錦、人聲如沸厘灼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽设凹。三九已至舰讹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闪朱,已是汗流浹背月匣。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工钻洒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锄开。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓素标,卻偏偏與公主長得像,于是被迫代替她去往敵國和親萍悴。 傳聞我的和親對象是個殘疾皇子头遭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容