Java Object 類別
Object 是 Java 中所有類別的根類別,每個類別都直接或間接繼承自 Object,因此所有物件都有 Object 定義的方法。
主要方法
public class Object {
public String toString();
public boolean equals(Object obj);
public int hashCode();
public final Class<?> getClass();
protected Object clone() throws CloneNotSupportedException;
public final void wait() throws InterruptedException;
public final void notify();
public final void notifyAll();
protected void finalize() throws Throwable; // 已棄用
}
toString()
預設回傳類別名稱和雜湊碼:
public class Person {
private String name;
private int age;
// 建議覆寫 toString
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
Person p = new Person("Alice", 25);
System.out.println(p); // Person{name='Alice', age=25}
equals() 和 hashCode()
預設行為
Object obj1 = new Object();
Object obj2 = new Object();
obj1.equals(obj2); // false(比較參考)
obj1 == obj2; // false
obj1.hashCode(); // 記憶體位址衍生的數值
覆寫 equals()
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
equals 和 hashCode 契約
- 相等的物件必須有相同的 hashCode
- hashCode 相同的物件不一定相等
- 覆寫 equals 就必須覆寫 hashCode
getClass()
Person p = new Person();
Class<?> clazz = p.getClass();
System.out.println(clazz.getName()); // com.example.Person
System.out.println(clazz.getSimpleName()); // Person
// 類型比較
if (p.getClass() == Person.class) {
System.out.println("是 Person 類型");
}
clone()
public class Person implements Cloneable {
private String name;
private int age;
@Override
protected Person clone() throws CloneNotSupportedException {
return (Person) super.clone(); // 淺複製
}
}
Person original = new Person("Alice", 25);
Person copy = original.clone();
深複製
public class Person implements Cloneable {
private String name;
private Address address;
@Override
protected Person clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = this.address.clone(); // 複製參考物件
return cloned;
}
}
執行緒相關方法
Object lock = new Object();
// wait/notify 必須在 synchronized 區塊內使用
synchronized (lock) {
lock.wait(); // 等待
lock.notify(); // 喚醒一個等待的執行緒
lock.notifyAll(); // 喚醒所有等待的執行緒
}
Objects 工具類別
import java.util.Objects;
// 空值安全的比較
Objects.equals(a, b);
// 產生 hashCode
Objects.hash(field1, field2, field3);
// 空值檢查
Objects.requireNonNull(obj, "不能為 null");
// 空值安全的 toString
Objects.toString(obj, "預設值");
// 判斷是否為 null
Objects.isNull(obj);
Objects.nonNull(obj);
Record 自動實作
Java 16+ 的 Record 自動實作 equals、hashCode、toString:
public record Person(String name, int age) {}
Person p1 = new Person("Alice", 25);
Person p2 = new Person("Alice", 25);
p1.equals(p2); // true
p1.hashCode(); // 自動生成
p1.toString(); // Person[name=Alice, age=25]
重點整理
- 所有類別都繼承自
Object - 覆寫
toString()提供有意義的字串表示 - 覆寫
equals()必須同時覆寫hashCode() getClass()取得物件的類別資訊clone()需要實作Cloneable介面- 使用
Objects工具類別簡化操作 - Record 類型自動實作這些方法