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);
}
Object,加 @Override 註解編譯器會校驗。null、再類型(推薦 getClass() 而非 instanceof,保證對稱性)。==,引用類型用 Objects.equals。equals **必須** 重寫 hashCode,保證 a.equals(b) ⇒ a.hashCode()==b.hashCode()。| 特性 | 重載 | 重寫 |
|---|---|---|
| 方法簽名 | 參數列表不同 | 完全相同 |
| 綁定時機 | 編譯期(靜態) | 運行期(動態) |
| 多態性 | 無 | 有 |
| 訪問修飾符 | 可縮小 | 不可縮小 |
equals/hashCode(Alt+Insert → Generate equals/hashCode)。Objects.equals、Objects.hash 簡化代碼(Java 7+)。「重載是為了方便調用者,重寫是為了多態」。
equals作為 Object 契約方法,**只能重寫,不能重載**——這是 Java 類庫設計的鐵律。