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

Java 物件深拷貝與淺拷貝完整解析與實作

     編輯:Java 相關知識

核心概念

  • 淺拷貝:僅複製物件本身及基本型別欄位,引用型別欄位仍指向同一記憶體位址。
  • 深拷貝:遞歸複製物件引用的所有物件,形成完全獨立的物件圖。

淺拷貝實作:Cloneable + clone()

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 實例

五種建立物件方式

  1. new 建構子
  2. Class.newInstance()(已棄用)
  3. Constructor.newInstance() 反射
  4. clone() 拷貝
  5. 反序列化 readObject()

選擇建議

場景推薦方式
簡單不可變物件建構子 / 建造者模式
需複製現有實例且欄位皆為基本型別/不可變物件淺拷貝 clone()
物件圖複雜、含可變引用深拷貝(序列化/第三方庫如 MapStruct、Jackson)
高效能、頻繁拷貝手寫拷貝構造函式或使用 ObjectMapper.convertValue()

注意事項

  • 實作 Cloneable 但未重寫 clone() 會拋 CloneNotSupportedException。
  • 序列化深拷貝要求所有參與類別實作 Serializable,且 serialVersionUID 穩定。
  • 序列化效能較差,不適合高頻熱路徑。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved