ITPub博客

首页 > 应用开发 > Java > Java 中如何实现深拷贝和浅拷贝?

Java 中如何实现深拷贝和浅拷贝?

原创 Java 作者:mingtian66 时间:2024-11-04 10:57:11 0 删除 编辑

在 Java 中,深拷贝和浅拷贝是两种复制对象的方式。它们的区别在于是否复制对象引用指向的内部对象。下面详细介绍它们的实现方式和区别。
1. 浅拷贝(Shallow Copy)

浅拷贝仅复制对象的基本数据类型和对其他对象的引用,而不复制引用对象本身。因此,浅拷贝后的对象和原对象共享相同的引用对象。若其中一个对象修改了引用对象的数据,另一个对象也会受到影响。
浅拷贝的实现方式

浅拷贝可以通过以下几种方法实现:

    使用 clone() 方法:实现 Cloneable 接口并覆盖 clone() 方法。

java

class Address {
    String city;

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

class Person implements Cloneable {
    String name;
    Address address;

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();  // 默认实现浅拷贝
    }
}

public class ShallowCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("New York");
        Person person1 = new Person("Alice", address);
        Person person2 = (Person) person1.clone(); // 浅拷贝

        System.out.println(person1.address.city);  // 输出: New York
        System.out.println(person2.address.city);  // 输出: New York

        // 修改 person2 的地址
        person2.address.city = "Los Angeles";
        System.out.println(person1.address.city);  // 输出: Los Angeles,影响到 person1
    }
}

在上面的例子中,person1 和 person2 的 address 字段指向相同的 Address 对象,所以修改 person2 的 address 会影响到 person1。
2. 深拷贝(Deep Copy)

深拷贝不仅复制对象的基本数据类型,还会递归地复制所有引用对象。这样,拷贝后的对象与原对象是完全独立的,修改其中一个对象的引用数据不会影响另一个对象。
深拷贝的实现方式

深拷贝的实现方式有多种,可以通过覆盖 clone() 方法、使用构造函数、或者序列化和反序列化等方式实现。

    覆盖 clone() 方法:对每个引用对象手动调用 clone() 以实现递归拷贝。

java

class Address implements Cloneable {
    String city;

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();  // 浅拷贝 Address 对象本身
    }
}

class Person implements Cloneable {
    String name;
    Address address;

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person clonedPerson = (Person) super.clone();
        clonedPerson.address = (Address) address.clone();  // 深拷贝 Address
        return clonedPerson;
    }
}

public class DeepCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("New York");
        Person person1 = new Person("Alice", address);
        Person person2 = (Person) person1.clone(); // 深拷贝

        System.out.println(person1.address.city);  // 输出: New York
        System.out.println(person2.address.city);  // 输出: New York

        // 修改 person2 的地址
        person2.address.city = "Los Angeles";
        System.out.println(person1.address.city);  // 输出: New York,不影响 person1
    }
}

在上面的例子中,通过对 address 字段进行递归拷贝,person1 和 person2 拥有独立的 Address 对象,修改 person2 的 address 不会影响 person1。

    使用序列化(仅适用于可序列化的对象):将对象序列化成字节流再反序列化,这样也可以实现深拷贝。此方法需要类实现 Serializable 接口。

java

import java.io.*;

class Address implements Serializable {
    String city;

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

class Person implements Serializable {
    String name;
    Address address;

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

    // 深拷贝方法
    public Person deepCopy() throws IOException, ClassNotFoundException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(this);

        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (Person) ois.readObject();
    }
}

public class DeepCopyWithSerialization {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Address address = new Address("New York");
        Person person1 = new Person("Alice", address);
        Person person2 = person1.deepCopy(); // 深拷贝

        System.out.println(person1.address.city);  // 输出: New York
        System.out.println(person2.address.city);  // 输出: New York

        // 修改 person2 的地址
        person2.address.city = "Los Angeles";
        System.out.println(person1.address.city);  // 输出: New York,不影响 person1
    }
}

总结

    浅拷贝:只复制对象的基本类型数据和对象引用(引用指向同一个对象)。
    深拷贝:递归地复制对象的所有内容,包括引用指向的对象,生成完全独立的新对象。

深拷贝在某些场景(如对象包含复杂嵌套对象)下会更安全,而浅拷贝则更适合简单对象的快速复制。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70040412/viewspace-3045083/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2024-08-07

  • 博文量
    589
  • 访问量
    603025