浅拷贝深拷贝

目录

一、浅拷贝 (Shallow Copy)

二、深拷贝 (Deep Copy)

三、总结


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

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

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

在编程中,深拷贝和浅拷贝是用于复制对象的两种不同方式。它们之间的主要区别在于它们如何处理引用类型的成员。

一、浅拷贝 (Shallow Copy)

浅拷贝创建一个新对象,这个新对象的属性包含与原对象相同的值。对于值类型(如整数、浮点数、布尔值等),它会直接复制这些值。而对于引用类型(如对象、数组等),它会复制引用,因此新对象中的属性和原对象中的属性引用同一个内存地址。

换句话说,浅拷贝只复制对象的第一层。如果对象中的属性是引用类型,那么浅拷贝不会复制这些引用类型对象,而是复制它们的引用。

例如:

public class Person implements Cloneable{
    public String name;
    public int age;
    public 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();
    }
}

class Address {
    public String city;
    public String street;

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

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("北京", "八里庄街道");
        Person person1 = new Person("李明", 30, address);
        Person person2 = (Person) person1.clone();

        System.out.println(person1.address.city); // 北京
        System.out.println(person2.address.city); // 北京

        person2.address.city = "洛杉矶";
        System.out.println(person1.address.city); // 洛杉矶
        System.out.println(person2.address.city); // 洛杉矶
    }
}

在上面的例子中,person1person2 都引用同一个 Address 对象,因此修改 person2.address.city 会影响到 person1.address.city

二、深拷贝 (Deep Copy)

深拷贝不仅复制对象本身,还递归地复制对象中引用的所有对象。因此,新对象和原对象是完全独立的,修改新对象不会影响到原对象。

例如:


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

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

    @Override
    protected Object clone(){
        Person cloned = null;
        try {
            cloned = (Person) super.clone();
            cloned.address = (Address) address.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        return cloned;
    }
}

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

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

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

注意看,深拷贝,Address类也实现了Clonable接口,重写了clone方法。


public class Main {
    public static void main(String[] args) {
        Address address = new Address("北京", "上海路");
        Person person1 = new Person("徐佳莹", 30, address);
        Person person2 = (Person) person1.clone();

        System.out.println(person1.address.city); // 北京
        System.out.println(person2.address.city); // 北京

        person2.address.city = "莫斯科";
        System.out.println(person1.address.city); // 北京
        System.out.println(person2.address.city); // 莫斯科
    }
}

在这个例子中,通过重写 clone 方法实现深拷贝,person1person2 拥有独立的 Address 对象,因此修改 person2.address.city 不会影响 person1.address.city

三、总结

  • 浅拷贝:只复制对象的第一层,引用类型成员仍然指向原来的对象。
  • 深拷贝:递归地复制对象和它包含的所有对象,生成完全独立的副本。
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值