java.lang.Object 是所有類的根父類,定義了對象通用行為。掌握其 7 個核心方法契約、默認實現與重寫規範,是寫出正確、高性能 Java 代碼的基石。
| 方法 | 用途 | 默認行為 | 重寫必要性 |
|---|---|---|---|
hashCode() | 哈希碼,哈希容器索引 | 對象地址衍生 (Native) | 配合 equals 必須重寫 |
equals(Object) | 邏輯相等性判斷 | 引用相等 (this == obj) | 值對象/實體類必須重寫 |
getClass() | 獲取運行時類對象 | Final,不可重寫 | 不可重寫 |
toString() | 對象文本表示 | 類名@十六進制哈希碼 | 強烈建議重寫,調試/日誌核心 |
clone() | 淺拷貝對象 | 拋 CloneNotSupportedException | 實現 Cloneable 並重寫為 public |
finalize() | GC 前清理鉤子 | 空實現 | 已棄用 (JDK 9+),勿使用 |
wait/notify/notifyAll | 線程協調 (監視器) | Native 實現 | 配合 synchronized 使用 |
// 必須滿足: // 1. 同一對象多次調用返回一致 (未修改 equals 依賴字段) // 2. equals 相等 → hashCode 必相等 // 3. hashCode 不相等 → equals 必不相等 (逆否命題) // 4. hashCode 相等 ≠ equals 相等 (允許碰撞,但應盡量減少)
public class Student implements Cloneable {
private String name;
private int age;
// 構造器、getter/setter 省略
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age); // JDK 7+ 推薦
}
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + '}';
}
@Override
protected Student clone() throws CloneNotSupportedException {
return (Student) super.clone(); // 淺拷貝,引用類型需深拷貝
}
}
@Test
public void testContract() {
Student s1 = new Student("John", 23);
Student s2 = new Student("John", 23);
Student s3 = s1;
// equals/hashCode 契約
assertTrue(s1.equals(s2));
assertEquals(s1.hashCode(), s2.hashCode());
assertTrue(s1.equals(s3));
// toString 可讀性
System.out.println(s1); // Student{name='John', age=23}
// clone 獨立性
Student s4 = s1.clone();
s4.setName("Jack");
assertEquals("John", s1.getName()); // 原對象不變
assertEquals("Jack", s4.getName());
}
Objects.equals()、Objects.hash() 處理 null 安全、減少樣板代碼try-with-resources / Cleaner / PhantomReference// 方案 A: getClass() == o.getClass() -- 嚴格,不支持子類相等 // 方案 B: o instanceof Student -- 寬鬆,支持子類,但需滿足對稱性/傳遞性 // 推薦:值對象用 getClass(),實體類用 instanceof + 狀態檢查
Object 方法看似簡單,實則蘊含豐富契約語義。內化這些規範,能避免 80% 集合框架、緩存、序列化、並發相關的疑難雜症。