关于浅拷贝,深拷贝以及深拷贝的实现方法

浅拷⻉:

浅拷⻉会在堆上创建⼀个新的对象(区别于引⽤拷⻉的⼀点),不过,如果原对象内部的属性是引⽤类型的话,浅拷⻉会直接复制内部对象的引⽤地址,也就是说拷⻉对象和原对象共⽤同⼀个内部对象。

深拷⻉ :

深拷⻉会完全复制整个对象,包括这个对象所包含的内部对象。

我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力。

在这里插入图片描述


如何实现深拷贝(深克隆)?

示例代码

class Person implements Cloneable {
    String name;
    int age;
    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 clonedPerson = (Person) super.clone();
        clonedPerson.address = (Address) this.address.clone();
        return clonedPerson;
    }
}

class Address implements Cloneable {
    String city;
    String state;

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

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

public class DeepCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("San Francisco", "CA");
        Person person1 = new Person("John", 30, address);

        Person person2 = (Person) person1.clone();

        System.out.println("Person1 address: " + person1.address.city); // 输出: San Francisco
        System.out.println("Person2 address: " + person2.address.city); // 输出: San Francisco

        person2.address.city = "Los Angeles";

        System.out.println("Person1 address after modification: " + person1.address.city); // 输出: San Francisco
        System.out.println("Person2 address after modification: " + person2.address.city); // 输出: Los Angeles
    }
}

注意以上是实现了cloneable接口。当然这种方法实在是太过于麻烦了。使用序列化来深克隆一个对象要简单得多,尤其是成员变量中有很多引用类型的时候。

使用序列化和反序列化来深拷贝一个对象
import java.io.*;

// 地址类实现Serializable接口
class Address implements Serializable {
    String city;
    String state;

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

    @Override
    public String toString() {
        return city + ", " + state;
    }
}

// 人类实现Serializable接口
class Person implements Serializable {
    String name;
    int age;
    Address address;

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

    @Override
    public String toString() {
        return name + " (" + age + "), " + address;
    }

    // 使用序列化进行深拷贝
    public Person deepCopy() throws IOException, ClassNotFoundException {
        // 将对象写入字节流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        oos.flush();
        oos.close();

        // 从字节流读取对象
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (Person) ois.readObject();
    }
}

public class DeepCopyUsingSerialization {
    public static void main(String[] args) {
        try {
            Address address = new Address("San Francisco", "CA");
            Person person1 = new Person("John", 30, address);

            // 深拷贝person1
            Person person2 = person1.deepCopy();

            System.out.println("Person1: " + person1); // 输出: John (30), San Francisco, CA
            System.out.println("Person2: " + person2); // 输出: John (30), San Francisco, CA

            // 修改person2的地址
            person2.address.city = "Los Angeles";

            System.out.println("Person1 after modification: " + person1); // 输出: John (30), San Francisco, CA
            System.out.println("Person2 after modification: " + person2); // 输出: John (30), Los Angeles, CA
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

如果觉得有帮助,欢迎点赞、收藏,以及小小支持一下。
本人博客地址:朗朗繁星的博客

  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值