java.lang 套件,無需顯式匯入protected Object clone() throws CloneNotSupportedException
使用條件:
Cloneable 標記介面,否則拋出異常public 供外部呼叫淺拷貝 vs 深拷貝:預設為淺拷貝(引用型別欄位共享同一物件),深拷貝需手動遞歸拷貝引用欄位。
Object 預設實作:
public boolean equals(Object obj) { return (this == obj); }
即預設等同於 == 比較記憶體位址。
覆寫契約(五大特性):
| 特性 | 規定 |
|---|---|
| 自反性 | x.equals(x) == true |
| 對稱性 | x.equals(y) ⇔ y.equals(x) |
| 傳遞性 | x.equals(y) ∧ y.equals(z) ⇒ x.equals(z) |
| 一致性 | 多次呼叫結果一致(前提:比較欄位未變) |
| 非空性 | x.equals(null) == false |
鐵律:覆寫 equals 必須同步覆寫 hashCode,反之亦然。
契約:
equals 判定相等 → hashCode 必須相等equals 不相等 → hashCode 可相同也可不同(但不同能提升雜湊表效能)Object 預設實作基於記憶體位址計算,適合身份比較;業務比較需依據業務鍵值計算。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
用途:System.out.println(obj) 自動呼叫。建議覆寫返回業務可讀資訊(如 "User{id=1, name='Tom'}"),利於除錯與日誌。
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id == user.id && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "'}";
}
官方 JavaDoc 與 JDK 原始碼(src.zip)是最權威教材。