java.lang.Object 定義了所有 Java 對象的公共行為,其中 equals() 和 toString() 是最常被覆寫的兩個方法。正確理解並實現它們,是編寫高質量 Java 代碼的基礎。
class Person {
String name; int age;
Person(String name, int age) { this.name = name; this.age = age; }
}
public class Demo {
public static void main(String[] args) {
Person p = new Person("lixin", 27);
Person q = new Person("jingxiaoqing", 21);
System.out.println(p.equals(q)); // false - 默認比較引用地址
System.out.println(p.toString()); // Person@15db9742 - 默認 類名@哈希碼
}
}

equals():默認使用 == 比較對象引用,即內存地址。toString():默認返回 getClass().getName() + "@" + Integer.toHexString(hashCode()),調試價值極低。x.equals(x) 返回 truex.equals(y) 返回 true ⇒ y.equals(x) 返回 truex.equals(y) 且 y.equals(z) ⇒ x.equals(z)x.equals(null) 返回 false@Override
public boolean equals(Object obj) {
if (this == obj) return true; // 同一引用
if (obj == null || getClass() != obj.getClass()) return null; // 空檢查 & 類型檢查
Person other = (Person) obj;
return Objects.equals(name, other.name) && age == other.age; // 核心字段比較
}
關鍵點:
Object,否則是重載而非覆寫。Objects.equals() 安全處理 null 值(Java 7+)。==,引用類型用 equals()。equals() 必須 覆寫 hashCode(),否則無法在 HashSet/HashMap 中正常工作。@Override
public int hashCode() {
return Objects.hash(name, age);
}
推薦格式:ClassName[field1=value1, field2=value2, ...]
@Override
public String toString() {
return "Person[name=" + name + ", age=" + age + "]";
}
// 或使用 Java 9+ Objects.toString()
return "Person[" + "name=" + name + ", age=" + age + "]";
toString()。@ToString.Exclude (Lombok) 或手動判斷。**** 或省略。Arrays.toString(arr)、List.toString() 已內部實現良好格式。右鍵 → Generate → equals() and hashCode() / toString(),勾選相關字段即可。
@Data // 包含 @EqualsAndHashCode + @ToString + @Getter/@Setter/@RequiredArgsConstructor
@EqualsAndHashCode(of = {"name", "age"}) // 指定比較字段
@ToString(exclude = {"password"}) // 排除敏感字段
public class User {
private String username;
private String password;
private int age;
}
編譯期自動生成標準實現,消除樣板代碼,減少錯誤。
| 錯誤 | 後果 | 修正 |
|---|---|---|
| 參數類型寫成具體類 | 重載而非覆寫,集合無法正常查找 | 參數必須是 Object |
| 只覆寫 equals 不覆寫 hashCode | HashSet 存入重複對象、HashMap get 失效 | 必須成對覆寫 |
| equals 中使用 instanceof 而非 getClass | 違背對稱性(子類實例 equals 父類實例可能為 true,反向為 false) | 嚴格用 getClass() 比較,或精心設計 instanceof 邏輯 |
| 比較浮點數用 == | 精度問題導致判斷錯誤 | 用 Float.compare / Double.compare 或設定誤差範圍 |
| toString 返回 null 或拋異常 | 日誌框架報錯、調試困難 | 保證非 null、無副作用、快速返回 |
equals() 定義業務邏輯上的「相等」,核心是選擇唯一標識字段(如 ID)或全字段比較(值對象)。toString() 服務於「可觀測性」,應清晰、完整、安全地展示對象狀態。Objects 工具類與 Lombok,讓代碼簡潔、正確、可維護。細節決定質量,從 equals 和 toString 開始,寫出專業的 Java 代碼。