Shaw0xyz 发表于 2024-7-8 11:50:47

Java 对象拷贝 - 浅拷贝与深拷贝的差异与应用

本帖最后由 Shaw0xyz 于 2024-7-8 12:16 编辑

1. 引言

在Java编程中,对象拷贝是一项常见操作。根据拷贝的深度不同,可以分为浅拷贝和深拷贝。理解这两种拷贝方式的差异及其应用场景,对于编写高效、安全的代码非常重要。本文将详细介绍Java中的浅拷贝与深拷贝,并通过示例代码说明它们的差异与应用。

2. 浅拷贝

2.1 浅拷贝的定义

浅拷贝是指创建一个新对象,这个新对象的属性与原对象的属性完全相同,但如果属性是对象类型,则拷贝的是引用而非对象本身。换句话说,浅拷贝只拷贝对象的一层。

2.2 浅拷贝的实现

浅拷贝通常通过实现Cloneable接口并覆盖clone方法来实现。

public class Person implements Cloneable {
    private String name;
    private int age;
    private Address address;

    public Person(String name, int age, Address address) {
      this.name = name;
      this.age = age;
      this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
      return super.clone();
    }

    // getters and setters
}

class Address {
    private String city;
    private String street;

    public Address(String city, String street) {
      this.city = city;
      this.street = street;
    }

    // getters and setters
}

2.3 浅拷贝的应用场景

浅拷贝适用于对象较为简单,且没有嵌套引用的情况。例如,在需要快速复制对象,且对嵌套对象的修改不会影响其他对象时,可以使用浅拷贝。

3. 深拷贝

3.1 深拷贝的定义

深拷贝是指创建一个新对象,并递归复制所有属性,包括所有嵌套对象。这样新对象与原对象完全独立,互不影响。

3.2 深拷贝的实现

深拷贝可以通过多种方式实现,包括实现Cloneable接口、序列化等。

3.2.1 通过Cloneable接口实现深拷贝

public class Person implements Cloneable {
    private String name;
    private int age;
    private Address address;

    public Person(String name, int age, Address address) {
      this.name = name;
      this.age = age;
      this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
      Person cloned = (Person) super.clone();
      cloned.address = (Address) address.clone();
      return cloned;
    }

    // getters and setters
}

class Address implements Cloneable {
    private String city;
    private String street;

    public Address(String city, String street) {
      this.city = city;
      this.street = street;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
      return super.clone();
    }

    // getters and setters
}

3.2.2 通过序列化实现深拷贝

import java.io.*;

public class Person implements Serializable {
    private String name;
    private int age;
    private Address address;

    public Person(String name, int age, Address address) {
      this.name = name;
      this.age = age;
      this.address = address;
    }

    public Person deepCopy() throws IOException, ClassNotFoundException {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(bos);
      oos.writeObject(this);

      ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
      ObjectInputStream ois = new ObjectInputStream(bis);
      return (Person) ois.readObject();
    }

    // getters and setters
}

class Address implements Serializable {
    private String city;
    private String street;

    public Address(String city, String street) {
      this.city = city;
      this.street = street;
    }

    // getters and setters
}

3.3 深拷贝的应用场景

深拷贝适用于对象结构复杂,包含多层嵌套对象的情况。尤其在多线程环境中,需要确保对象的独立性,避免因共享对象导致数据不一致时,深拷贝是一个很好的选择。

4. 浅拷贝与深拷贝的差异

4.1 拷贝内容

(1) 浅拷贝只复制对象的基本类型和引用类型,引用类型只复制引用地址。
(2) 深拷贝不仅复制对象的基本类型,还递归复制引用类型指向的对象。

4.2 内存使用

(1) 浅拷贝占用的内存较少,因为只复制基本类型和引用地址。
(2) 深拷贝占用的内存较多,因为需要复制所有嵌套对象。

4.3 性能

(1) 浅拷贝速度较快,因为复制的内容较少。
(2) 深拷贝速度较慢,因为需要递归复制所有嵌套对象。

5. 结论

浅拷贝与深拷贝各有优缺点,适用于不同的应用场景。理解它们的差异,并根据具体需求选择合适的拷贝方式,对于编写高效、安全的Java代码至关重要。希望本文能帮助读者深入理解Java对象拷贝的概念,并在实际开发中灵活应用。如果有任何问题或建议,欢迎讨论交流。








/ 荔枝学姐de课后专栏 /

Hi!这里是荔枝学姐~

欢迎来到我的课后专栏

自然语言学渣 NLP摆烂姐

热衷于技术写作 IT边角料

AIGC & Coding & Linux ...

~互撩~ TG: @Shaw_0xyz
页: [1]
查看完整版本: Java 对象拷贝 - 浅拷贝与深拷贝的差异与应用