Java中的浅拷贝和深拷贝

浅拷贝仅复制对象的基本数据类型和引用地址,而深拷贝复制整个对象及其引用的对象,防止数据混乱和内存泄漏。文章通过示例代码展示了浅拷贝和深拷贝的实现,并指出在多线程编程中深拷贝的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

浅拷贝和深拷贝是Java中常用的两种对象拷贝方式。浅拷贝只复制对象的基本数据类型的值和引用类型的地址,而不复制引用对象本身;深拷贝则是完全复制对象及其引用的对象,包括基本数据类型和引用类型。

浅拷贝和深拷贝的应用方向不同:

浅拷贝适用于对象比较简单的情况,例如只包含基本数据类型和少量引用类型,且引用类型的对象比较简单。在这种情况下,浅拷贝可以很方便地复制对象,同时也不会造成内存泄漏等问题。

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;
    }

    // 实现Cloneable接口,重写clone()方法
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("China", "Beijing");
        Person person1 = new Person("Tom", 20, address);
        Person person2 = (Person) person1.clone();

        // 修改person1的address属性
        person1.getAddress().setCity("Shanghai");

        // 输出person1和person2的address属性
        System.out.println(person1.getAddress().getCity()); // 输出"Shanghai"
        System.out.println(person2.getAddress().getCity()); // 输出"Shanghai"
    }

    // getter和setter方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

class Address {
    private String country;
    private String city;

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

    // getter和setter方法
    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

 ​​​​​​

深拷贝适用于对象比较复杂的情况,例如对象包含多个引用类型,或引用类型的对象也包含多个引用类型,这种情况下,如果使用浅拷贝,复制出来的对象可能会共享同一个引用对象,导致数据混乱或者内存泄漏等问题。而深拷贝则可以完全复制对象及其引用的对象,避免了这些问题。

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;
    }

    // 实现Cloneable接口,重写clone()方法
    @Override
    public Object clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();
        person.address = (Address) address.clone();
        return person;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("China", "Beijing");
        Person person1 = new Person("Tom", 20, address);
        Person person2 = (Person) person1.clone();

        // 修改person1的address属性
        person1.getAddress().setCity("Shanghai");

        // 输出person1和person2的address属性
        System.out.println(person1.getAddress().getCity()); // 输出"Shanghai"
        System.out.println(person2.getAddress().getCity()); // 输出"Beijing"
    }

    // getter和setter方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

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

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

    // 实现Cloneable接口,重写clone()方法
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    // getter和setter方法
    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

在多线程编程中,深拷贝也比较常用。由于多个线程可能会同时访问同一个对象,如果使用浅拷贝,可能会导致数据竞争等问题。而使用深拷贝则可以避免这些问题,每个线程都拥有自己的独立对象。

浅拷贝(Shallow Copy)是指创建一个新的对象,新对象的属性和原对象的属性都是相同的,但是两个对象引用的是同一个对象。也就是说,新对象的属性值只是原对象属性值的一个副本,但是两个对象的属性引用的是同一个对象。因此,当原对象的属性发生变化时,新对象的属性也会发生变化。

深拷贝(Deep Copy)是指创建一个新的对象,新对象的属性和原对象的属性都是相同的,但是两个对象引用的是不同的对象。也就是说,新对象的属性值和原对象的属性值都是一个副本,但是两个对象的属性引用的是不同的对象。因此,当原对象的属性发生变化时,新对象的属性不会发生变化。

总之,浅拷贝和深拷贝都有各自的应用方向。在实际编程中,需要根据具体的情况选择合适的拷贝方式,以保证程序的正确性和性能。

需要注意的是,进行深拷贝可能会导致对象的复制过程变得复杂和耗时,因此需要根据具体情况选择合适的对象复制方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ヾ草木萤火(≧▽≦*)o

希望大家多多支持,我会继续分享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值