class MyString implements Cloneable {
private String s;
MyString(String s) { this.s = s; }
public String toString() { return s; }
void concatenate(String tail) { s += tail; }
public Object clone() {
try { return super.clone(); } // String 不可變,淺拷貝即可
catch (CloneNotSupportedException e) { throw new RuntimeException(e); }
}
// 測試:兩個 static 方法,一個直接 concatenate,一個 clone 後 concatenate
// 觀察原對象是否被修改
}
class Battery { int id; Battery(int id) { this.id = id; } }
class Toy implements Cloneable {
Battery[] batteries;
Toy(int n) { batteries = new Battery[n]; for(int i=0;i
練習 3:CheckCloneable 異常內部處理
修改所有 clone() 捕獲 CloneNotSupportedException 內部轉為 RuntimeException,不向上拋出受檢異常,簡化調用端代碼。
練習 4:Compete 性能分析
為 Thing2、Thing4 添加更多成員對象,測量 clone() 時間隨復雜度增長曲線。通常呈線性關係(每個成員對象 clone 耗時相加),但對象圖共享/循環引用可能導致非線性。
練習 5:Snake 深拷貝
Snake 內部持有 SnakeSection[],每節含 SnakeSection 引用形成鏈表。深拷貝需遞歸拷貝每節,並維護新鏈表的 next 指針正確指向新節點,避免新舊對象交織。
核心原則
clone() 契約:
1. 實現 Cloneable(標記接口)
2. 覆寫 clone() 為 public
3. 調用 super.clone() 獲取淺拷貝
4. 手動深拷貝所有可變成員對象/數組
5. 異常內部處理或聲明拋出