上次在公眾號發(fā)布了一篇EffectiveJava的筆記創(chuàng)建和銷毀對象,有人反應字數(shù)太多了,一下子看不過來,于是我考慮著要不每次學一點,分享一點,然后再在每章學習結束再匯總整理一篇,這樣方便大家閱讀,也有利于碎片時間吸收知識,也能提升一下文章的更新頻率,一舉多得
依然要提的是,本人能力有限,EffectiveJava比較難懂,所以不免有疏漏或錯誤的地方,非常歡迎大家批評指正!!!
上次黑燕同學就提醒我:Long裝箱后,會形成一個8b的Markword,8b的指針牵署,8b的真正數(shù)據(jù)絮短,所以效率只有1/3了 詳細解釋了為什么基本類型性能更加優(yōu)秀
在這里表示一下感謝!!
好了接下去,正文~
第8條 覆蓋equals時請遵守通用約定
不覆蓋equals
不覆蓋equals的情況下,類的每個實例都與它自身相等,如果滿足以下任何一個條件,就是所期望的結果:
- 類的每個實例本質上都是唯一的
- 不關心類是否提供了"邏輯相等"的測試功能
- 超類已經(jīng)覆蓋了equals,從超類繼承過來的行為對于子類也是合適的(要小心)
- 類是私有的或是包級私有的,可以確定它的equals方法永遠不會被調用 (不懂為什么)
講得怪怪的
PS: 邏輯相等,就是邏輯上是相等的,比如id一樣,判定它們相等,即使它們是兩個不同的對象
什么時候應該覆蓋equals
當類需要邏輯相等這個概念的時候就應該覆蓋equals
比如要判斷兩個student
是否是同一個人,這個時候我們就需要按需重寫equals
通用約定
重寫equals的時候就必須要遵守它的通用約定
equals方法實現(xiàn)了等價關系(equivalence relation):
- 自反性(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)就會一致地返回true,或者false
- 對于任何非null的引用值,x,x.equals(null)必須返回false
感覺又回到了學數(shù)學交換律什么的的時候了~
有些類(如集合,HashMap)與equals
方法息息相關,所以重寫的時候要仔細小心
高質量的equals
ej對equals提了幾點建議:
- 使用
==
操作符檢查"參數(shù)是否為這個對象的引用" 如果是,則返回true. 這只不過是一種性能優(yōu)化,如果比較操作有可能很昂貴,就值得這么做 (平時沒有用過,怎么樣的比較操作算是昂貴的呢?) - 使用
instanceof
操作符檢查"參數(shù)是否為正確的類型" 如果不是,則返回false。 - 把參數(shù)裝換成正確的類型刘离。(這個比較好理解,instanceof檢測后,一般都會強轉成所需類型)
- 對于該類中的每個『關鍵』域,檢查參數(shù)中的域是否與對象中對應的域相配。(比如學生類有學號,班級闹获,姓名這些重要的屬性,我們都需要去比對)
- 當你編寫完成了equals方法之后河哑,應該問自己是哪個問題:它是否是對稱的避诽、傳遞的、一致的灾馒?
另外EJ還告誡我們覆蓋equals的時候總要覆蓋hashCode(見第9條)
小結
最后按照上訴建議茎用,用一個Student
類來總結一下equals的寫法:
public class Student {
public String name;
public String className;
@Override
public boolean equals(Object obj) {
//對于一個null的對象 我們總是返回false
if (null == obj) {
return false;
}
// 利用instanceof檢查類型后,強轉
if (obj instanceof Student){
Student other = (Student) obj;
//再對關鍵的屬性做比較 得出結論
if (name.equals(other.name) && className.equals(other.className)) {
return true;
}
}
return false;
}
}
equals
是一個看上去簡單,實則是個比較容易犯錯的方法,需要小心仔細
好了,這是這一條學習筆記的全部內容,如果你有什么建議和意見,歡迎與我交流