1. 程式人生 > >基礎 | 重寫equals方法

基礎 | 重寫equals方法

參加VIVO秋招面試中,在回答「Object類有哪些方法?每個方法分別有什麼作用?」問題時,提到equals()方法,就又被問到 「在重寫equals()方法需要注意什麼?」,頓時就一臉懵逼,這也是面試「Java開發工程師」過程中的高頻問題,在此進行一個系統的總結與梳理。


參考答案

為什麼要重寫equals()方法?

Object類中equals()方法的預設實現主要是用於判斷兩個物件的引用是否相同。而在實際開發過程中,通常需要比較兩個物件的對應屬性是否完全相同,故需要重寫equals()方法。

如何重寫equals()方法?

假設equals()方法的形參名為otherObj,稍後需要將其轉換為另一個叫做other的變數。

第一步,檢測this與otherObj是否引用同一物件:

if(this == otherObject) return true;

第二步,檢測otherObj是否為空:

if(otherObject == null) return false;

第三步,判斷this與otherObj是否屬於同一個類,具體分兩種情況:

(1). 如果equals()方法的語義在每個子類中均有所改變,則使用getClass()方法進行檢測:

if(getClass() != otherObject.getClass()) return false;

(2). 如果equals()方法在所有子類中均有統一的語義,則使用instanceof關鍵字進行檢測:

if (!(otherObject instanceof ClassName)) return false;

第四步,將otherObj轉換為相應類的型別變數:

ClassName other = (ClassName) otherObject;

第五步,對所有需要比較的域進行一一比較,若全匹配則返回true,否則返回false。

關於equals()語義的補充說明:假設現有Employee與Manager兩個類,Manager類繼承Employee類。若僅將ID作為相等的檢測標準,則僅用在Employee類中重寫equals()方法,並將該方法宣告為final的即可,這就是所謂的「擁有統一的語義」。

重寫equals()方法需要注意什麼?

歸根結底,還是想問equals()方法的主要特性。Java語言規範要求equals()方法具有如下特性:

  • 自反性:對於任何非空引用x,x.equals(x)應該返回true。
  • 對稱性:對於任何引用x和y,當且僅當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引用的物件沒有發生變化,反覆呼叫x.equals(y)應該返回同樣的結果。
  • 非空性:對於任何非空引用x,x.equals(null)應該返回false。

原始碼閱讀

// Object類中equals()方法的預設實現
public boolean equals(Object obj) {
    return (this == obj);
}
// String類中equals()方法的具體實現
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    // 具有統一語義
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

推薦閱讀


歡迎關注

Java名企面試吧,每天10點24分,我們不見不散!

丙子先生的宗旨是,每天以短篇幅講高頻面試題,不增加太多負擔,但需要持之以恆。

能力有限,歡迎指教!