最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中實現(xiàn)對象深克隆的四種方式

 更新時間:2025年10月29日 09:48:32   作者:qincloudshaw  
這篇文章主要介紹了如何在Java中實現(xiàn)對象的深克隆,可以通過手動實現(xiàn)clone()方法、使用序列化、第三方庫Apache Commons Lang或Hutool等幾種方式,每種方式都有其特點,需要的朋友可以參考下

在Java中實現(xiàn)對象的深克隆(Deep Clone)需要確保對象及其所有引用類型的字段都被復(fù)制,而不是共享相同的內(nèi)存地址。以下是幾種常見的實現(xiàn)方式:

方法1:手動實現(xiàn)深克隆

通過重寫 clone() 方法并逐層復(fù)制引用對象:

@Data
@AllArgsConstructor
@NoArgsConstructor
class Address implements Cloneable {
    private String city;
    
    @Override
    protected Address clone() throws CloneNotSupportedException {
        return (Address) super.clone();
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Person implements Cloneable {
    private String name;
    private Address address;
    private List<String> hobbies;

    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        // 深克隆引用對象
        cloned.address = this.address.clone();
        // 若hobbies是自定義對象列表,需逐個深克隆
        return cloned;
    }
}

public class DeepCloneExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address addr = new Address("Beijing");
        List<String> hobbies = List.of("reading", "swimming");
        Person p1 = new Person("Alice", addr, hobbies);
        
        // 深克隆
        Person p2 = p1.clone();
        
        // 修改克隆對象的屬性,不會影響原對象
        p2.getAddress().setCity("Shanghai");
        p2.getHobbies().add("running");
        
        System.out.println(p1.getAddress().getCity()); // 輸出: Beijing
        System.out.println(p2.getAddress().getCity()); // 輸出: Shanghai
        System.out.println(p1.getHobbies()); // 輸出: [reading, swimming]
        System.out.println(p2.getHobbies()); // 輸出: [reading, swimming, running]
    }
}

關(guān)鍵點:

  1. 實現(xiàn) Cloneable 接口:標(biāo)記類支持克隆。
  2. 重寫 clone() 方法:調(diào)用 super.clone() 后,手動復(fù)制引用類型字段。
  3. 逐層深克隆:對每個引用對象(如 Address)也需實現(xiàn)深克隆。

方法2:使用序列化 Serializable

通過序列化和反序列化實現(xiàn)深克隆:

@Data
@AllArgsConstructor
@NoArgsConstructor
class Address implements Serializable {
    private static final long serialVersionUID = 1L;
    private String city;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private Address address;
    private List<String> hobbies;
    
    // 深克隆方法
    public Person deepClone() {
      // 序列化
      try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"))) {
          oos.writeObject(this);
      } catch (Exception e) {
          e.printStackTrace();
      }

      // 反序列化
      try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"))) {
          return (Person) ois.readObject();
      } catch (Exception e) {
          e.printStackTrace();
      }
        
    }
}

public class DeepCloneBySerialization {
    public static void main(String[] args) {
        Address addr = new Address("Beijing");
        List<String> hobbies = new ArrayList<>(List.of("reading", "swimming"));
        Person p1 = new Person("Alice", addr, hobbies);
        
        // 深克隆
        Person p2 = p1.deepClone();
        
        // 修改克隆對象的屬性,不會影響原對象
        p2.getAddress().setCity("Shanghai");
        p2.getHobbies().add("running");
        
        System.out.println(p1.getAddress().getCity()); // 輸出: Beijing
        System.out.println(p2.getAddress().getCity()); // 輸出: Shanghai
        System.out.println(p1.getHobbies()); // 輸出: [reading, swimming]
        System.out.println(p2.getHobbies()); // 輸出: [reading, swimming, running]
    }
}

使用 ByteArrayOutputStream 將對象序列化為內(nèi)存中的字節(jié)數(shù)組。 再通過 ByteArrayInputStream 從內(nèi)存中讀取該字節(jié)數(shù)組并反序列化成新對象。 整個過程不涉及任何磁盤 I/O,完全在內(nèi)存中完成,效率更高。

import java.io.*;

public class DeepCloneUtil {
    public static <T extends Serializable> T deepClone(T object) {
        try (
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
        ) {
            // 序列化對象到內(nèi)存中的字節(jié)數(shù)組
            oos.writeObject(object);

            try (
                ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bis);
            ) {
                // 反序列化并返回新對象
                return (T) ois.readObject();
            }
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException("深克隆失敗", e);
        }
    }

    public static void main(String[] args) {
        Address address = new Address("Beijing");
        Person person1 = new Person("Alice", address, List.of("reading", "swimming"));

        // 深克隆
        Person person2 = DeepCloneUtil.deepClone(person1);

        // 修改克隆對象的屬性,不會影響原對象
        person2.getAddress().setCity("Shanghai");

        System.out.println(person1.getAddress().getCity()); // 輸出: Beijing
        System.out.println(person2.getAddress().getCity()); // 輸出: Shanghai
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Address implements Serializable {
    private static final long serialVersionUID = 1L;
    private String city;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private Address address;
    private List<String> hobbies;
}

關(guān)鍵點:

  1. 實現(xiàn) Serializable 接口:所有類(包括嵌套類)必須可序列化。
  2. 通過流操作:將對象序列化為字節(jié)流,再反序列化為新對象,確保所有引用都被復(fù)制。
  3. 自動處理嵌套對象:無需手動逐層克隆

方法3:使用第三方庫 Apache Commons Lang(推薦使用,因為一般項目中都會引入這個依賴)

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>

使用 SerializationUtils.clone()

import org.apache.commons.lang3.SerializationUtils;

// 確保所有類實現(xiàn)Serializable接口
class Address implements Serializable { /* ... */ }
class Person implements Serializable { /* ... */ }

public class DeepCloneWithLibrary {
    public static void main(String[] args) {
        // 創(chuàng)建對象
        Person p1 = new Person("Alice", new Address("Beijing"), List.of("reading"));
        
        // 深克隆
        Person p2 = SerializationUtils.clone(p1);
        
        // 修改克隆對象,不影響原對象
        p2.getAddress().setCity("Shanghai");
    }
}

方法4:使用第三方庫 Hutool

使用 CloneUtil.cloneByStream(obj)

需要對象及其嵌套對象實現(xiàn) java.io.Serializable 接口

@Data
@AllArgsConstructor
@NoArgsConstructor
class Address implements java.io.Serializable {
  private String city;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Person implements java.io.Serializable {
  private String name;
  private Address address;
}

public class HutoolDeepCloneExample {
  public static void main(String[] args) {
    Address addr = new Address("Beijing");
    Person p1 = new Person("Alice", addr);
    
    Person p2 = CloneUtil.cloneByStream(p1);
    
    p2.getAddress().setCity("Shanghai"); // 修改克隆對象的屬性,不會影響原對象
    System.out.println(p1.getAddress().getCity()); // 輸出: Beijing
    System.out.println(p2.getAddress().getCity()); // 輸出: Shanghai
  }
}

到此這篇關(guān)于Java中實現(xiàn)對象深克隆的四種方式的文章就介紹到這了,更多相關(guān)Java實現(xiàn)對象深克隆內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

深水埗区| 慈利县| 松潘县| 寿光市| 梅河口市| 昌都县| 海阳市| 西乡县| 潼南县| 怀柔区| 五指山市| 塔城市| 颍上县| 凤山县| 特克斯县| 桦南县| 临澧县| 台山市| 佛山市| 中牟县| 顺昌县| 临沭县| 嘉祥县| 高碑店市| 永修县| 逊克县| 林周县| 佛坪县| 惠来县| 安陆市| 常熟市| 新巴尔虎右旗| 志丹县| 海晏县| 大邑县| 厦门市| 常熟市| 大英县| 大城县| 西峡县| 固安县|