class ClassInfo { String name; /* getter/setter */ }
class User implements Cloneable {
String name; Long id; ClassInfo clazz;
@Override protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 預設淺拷貝
}
}
// 測試
User u1 = new User(); u1.setClazz(new ClassInfo("Math"));
User u2 = (User) u1.clone();
System.out.println(u1.getClazz() == u2.getClazz()); // true:同一 ClassInfo 實例
class Car implements Serializable {
private static final long serialVersionUID = 1L;
String name; /* getter/setter */
}
class People implements Serializable {
private static final long serialVersionUID = 1L;
Car car; /* getter/setter */
People deepClone() throws IOException, ClassNotFoundException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(this);
try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis)) {
return (People) ois.readObject();
}
}
}
}
// 測試
People p1 = new People(); p1.setCar(new Car("Benz"));
People p2 = p1.deepClone();
System.out.println(p1.getCar() == p2.getCar()); // false:獨立 Car 實例
new 建構子Class.newInstance()(已棄用)Constructor.newInstance() 反射clone() 拷貝readObject()| 場景 | 推薦方式 |
|---|---|
| 簡單不可變物件 | 建構子 / 建造者模式 |
| 需複製現有實例且欄位皆為基本型別/不可變物件 | 淺拷貝 clone() |
| 物件圖複雜、含可變引用 | 深拷貝(序列化/第三方庫如 MapStruct、Jackson) |
| 高效能、頻繁拷貝 | 手寫拷貝構造函式或使用 ObjectMapper.convertValue() |
Cloneable 但未重寫 clone() 會拋 CloneNotSupportedException。Serializable,且 serialVersionUID 穩定。