深拷貝需遞歸複製對象圖中所有引用對象。本文提供工具類 DeepCopy,自動嘗試兩種方案:
Serializable。net.sf.json.JSONObject(json-lib),無需實作介面,但需無參構造器與 Setter/Getter。public class DeepCopy {
public static T copy(T obj) throws Exception {
// 1. 嘗試 Java 序列化
if (Serializable.class.isAssignableFrom(obj.getClass())) {
try { return copyImplSerializable(obj); } catch (Exception ignored) {}
}
// 2. 回退 JSON 序列化
if (hasJson()) {
try { return copyByJson(obj); } catch (Exception ignored) {}
}
return null;
}
@SuppressWarnings("unchecked")
private static T copyImplSerializable(T obj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
T result = (T) ois.readObject();
oos.close(); ois.close(); baos.close(); bais.close();
return result;
}
private static boolean hasJson() {
try { Class.forName("net.sf.json.JSONObject"); return true; }
catch (Exception e) { return false; }
}
@SuppressWarnings("unchecked")
private static T copyByJson(T obj) throws Exception {
return (T) JSONObject.toBean(JSONObject.fromObject(obj), obj.getClass());
}
}
User original = new User("Alice", new Address("Beijing"));
User cloned = DeepCopy.copy(original);
cloned.getAddress().setCity("Shanghai");
// original 不受影響
| 維度 | Java 序列化 | JSON 序列化 |
|---|---|---|
| 前置條件 | 所有類實作 Serializable | 引入 json-lib,類有無參構造器 |
| 性能 | 較快(二進制) | 較慢(文本解析) |
| 跨語言 | 不支援 | 天然支援 |
| 透明度 | 高(無侵入業務代碼) | 需依賴第三方庫 |
現代專案建議考慮 Jackson/Gson 替代 json-lib,或使用 MapStruct、Cloneable 手寫拷貝以獲得最佳性能與類型安全。