首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java equals 方法重載導致多態失效深度解析

     編輯:程式設計綜合問答

問題代碼

class Test {
    private String value;
    public Test(String v) { value = v; }
    // 重載而非重寫
    public boolean equals(Test o) { ... }
}

Test test1 = new Test("aa");
Object obj = new Test("aa");
System.out.println(test1.equals(obj)); // 輸出 false

核心原因

  • Object.equals(Object) 是**實例方法**,支持動態分派(多態)。
  • Test.equals(Test) 是**重載**,參數類型不同,屬於靜態綁定(編譯期決議)。
  • 調用時 obj 編譯時類型為 Object,編譯器綁定 Object.equals(Object),運行時**不會**自動調用子類重載版本。

正確重寫模板

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Test test = (Test) o;
    return Objects.equals(value, test.value);
}

關鍵規則(Effective Java)

  1. 參數必須為 Object,加 @Override 註解編譯器會校驗。
  2. 先檢查引用相等、再 null、再類型(推薦 getClass() 而非 instanceof,保證對稱性)。
  3. 比較所有關鍵字段,基本類型用 ==,引用類型用 Objects.equals。
  4. 重寫 equals **必須** 重寫 hashCode,保證 a.equals(b) ⇒ a.hashCode()==b.hashCode()。

對比:重載 vs 重寫

特性重載重寫
方法簽名參數列表不同完全相同
綁定時機編譯期(靜態)運行期(動態)
多態性無有
訪問修飾符可縮小不可縮小

最佳實踐

  • IDE 自動生成 equals/hashCode(Alt+Insert → Generate equals/hashCode)。
  • 使用 Objects.equals、Objects.hash 簡化代碼(Java 7+)。
  • 不可變類(如 String、Integer)已正確實現,直接復用。

「重載是為了方便調用者,重寫是為了多態」。equals 作為 Object 契約方法,**只能重寫,不能重載**——這是 Java 類庫設計的鐵律。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved