首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 設計模式:原型模式深度解析 — 淺拷貝、深拷貝與序列化實現

     編輯:Java 綜合教學

Java 設計模式:原型模式深度解析 — 淺拷貝、深拷貝與序列化實現

原型模式通過拷貝現有對象創建新對象,避免昂貴的構造過程。Java Cloneable 接口提供語言級支援,但深淺拷貝細節決定成敗。

三種對象複製層次對比

對象賦值:引用複製,指向同一堆內存
賦值:s2 = s1,雙方引用同一對象,修改互影響
淺拷貝:對象新建,但引用類型字段共享
淺拷貝:clone() 默認行為,基本類型/不可變對象複製,可變對象共享引用

淺拷貝陷阱實證

class Student implements Cloneable {
    String name;           // 不可變,拷貝安全
    List friends;  // 可變,淺拷貝共享!
    
    @Override protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 默認淺拷貝
    }
}

// 測試
Student s1 = new Student(); s1.friends = new ArrayList<>(Arrays.asList("紅","梅"));
Student s2 = (Student) s1.clone();
s2.friends.add("剛"); // 修改 s2 的列表
System.out.println(s1.friends); // [紅, 梅, 剛] ← s1 也被修改了!
System.out.println(s2.friends); // [紅, 梅, 剛]

結論:clone() 默認實現淺拷貝,可變引用類型字段共享底層對象。

深拷貝實現方案:序列化反序列化

原理:對象 → 字節流 (持久化) → 新對象,完全獨立內存。

public Object deepClone() throws IOException, ClassNotFoundException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(this); // 要求實現 Serializable
    
    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    return ois.readObject(); // 返回全新獨立對象圖
}

前提:對象及所有引用字段必須實現 Serializable,transient 字段不會被拷貝。

原型模式類結構

原型模式類圖:Prototype接口定義clone(),ConcretePrototype實現
原型模式標準結構:Prototype 聲明 clone(),具體原型實現拷貝邏輯

適用場景與選型指南

拷貝方式性能適用場景注意事項
賦值引用極快只讀共享、飛量模式修改互影響
淺拷貝 clone()快字段全為基本類型/不可變對象可變字段共享風險
深拷貝序列化較慢複雜對象圖、含可變引用字段需 Serializable、transient 處理
深拷貝手動 new中等高性能要求、精確控制拷貝邏輯代碼冗長、維護成本高

最佳實踐建議

  1. 優先考慮不可變對象設計,從根源消除拷貝需求
  2. 使用 copy constructor 或 static factory copy 替代 clone() (Effective Java 項目 13)
  3. 必須用 clone() 時:實現 Cloneable、覆寫 public clone()、決定深淺策略並文檔化
  4. 深拷貝首選序列化,或引入 Apache Commons Lang SerializationUtils.clone()

原型模式核心價值:以拷貝代替創建,隱藏具體構造細節,支援運行時動態配置對象類型。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved