class Body implements Cloneable {
int height;
@Override protected Body clone() {
try { return (Body) super.clone(); }
catch (CloneNotSupportedException e) { throw new AssertionError(); }
}
}
class Person implements Cloneable {
String name; Body body;
@Override protected Person clone() {
try { return (Person) super.clone(); } // body 為引用,淺拷貝
catch (CloneNotSupportedException e) { throw new AssertionError(); }
}
}
// 測試
Person p1 = new Person("A", new Body(180));
Person p2 = p1.clone();
p2.body.height = 170;
System.out.println(p1.body.height); // 170 → 原對象被修改!
@Override protected Person clone() {
Person p = (Person) super.clone();
p.body = body.clone(); // 關鍵:手動深拷貝引用字段
return p;
}
// 測試
p2.body.height = 170;
System.out.println(p1.body.height); // 180 → 原對象不變
import java.io.*;
public class CloneUtil {
@SuppressWarnings("unchecked")
public static T deepClone(T obj) {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(obj);
try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis)) {
return (T) ois.readObject();
}
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("深拷貝失敗", e);
}
}
}
// 使用:所有類實現 Serializable
class Teacher implements Serializable { String name; int age; }
class Student implements Serializable { String name; Teacher teacher; }
Teacher t = new Teacher("老王", 40);
Student s1 = new Student("小明", t);
Student s2 = CloneUtil.deepClone(s1);
s2.teacher.name = "老李";
System.out.println(s1.teacher.name); // 老王 → 完全隔離
// 構造器複製 (手寫 new) : ~30 ms (最快,推薦簡單對象)
// clone() 遞歸 : ~60 ms
// Apache SerializationUtils : ~450 ms
// JSON (Jackson) 序列化反序列化: ~800 ms
結論:**構造器/工廠複製最快**,clone() 次之,序列化/JSON 適合複雜對象圖或跨進程傳輸。
transient 字段序列化會丟失 (為 null/默認值),深拷貝時需注意。new ArrayList<>(list) 只是淺拷貝元素,需流式 list.stream().map(e -> deepClone(e)).collect(...)。clone() 遞歸。深拷貝是手段,**消除可變共享狀態** 才是目的。