先看個範例, 取自 AbstractSet 補加個 @Override:
@Override // #1 public boolean equals(Object o) { if (o == this) // #2 return true; if (!(o instanceof Set)) // #3 return false; Collection c = (Collection) o; // #4 if (c.size() != size()) // #5 return false; try { return containsAll(c); // #6 } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } }覆寫 equals 時的注意事項:
- 加 @Override 確保沒覆寫錯 method, 常見錯誤是參數寫成 MyClass o
- 先比 reference, 比較有效率
- 再來要檢查型別。由於 null 不屬於任何 class 或 interface, 用 instanceof 也可確保傳入的物件不是 null, 不必多加一步檢查 null
- 若是 interface 就轉 interface, 再用 method 比較; 若是 class 就能直接取 field 比值。比 field 時可用這個寫法同時考慮 null 的情況:
(field == o.field || (field != null && field.equals(o.field)))
- 先比低運算成本的項目。hashCode 或一些 summary value 是不錯的選擇
- 再比高運算成本的項目
- 寫 unit test 檢查 symmetric、transitive、consistent
- 有覆寫 equals 時, 一定要覆寫 hashCode (見 item 9)