Java对象深拷贝与浅拷贝的区别


在 Java 编程中,深拷贝和浅拷贝是对象复制的两种方式,它们在处理对象的引用类型时表现不同。

一、浅拷贝

浅拷贝是指创建一个新对象,并将原对象的字段值复制到新对象中。如果字段是基本数据类型,则直接复制其值;如果字段是引用类型,则复制的是引用(即两个对象的引用字段指向同一个内存地址)。

示例代码

class Address {
    String street;
    String city;

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

class Person {
    String name;
    Address address;

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

public class ShallowCopyExample {
    public static void main(String[] args) {
        Address originalAddress = new Address("123 Main St", "Anytown");
        Person originalPerson = new Person("John Doe", originalAddress);

        // 浅拷贝
        Person copiedPerson = new Person(originalPerson.name, originalPerson.address);

        // 修改拷贝对象的地址
        copiedPerson.address.city = "New City";

        System.out.println("Original person's address: " + originalPerson.address.city);
        System.out.println("Copied person's address: " + copiedPerson.address.city);
    }
}

输出结果

Original person's address: New City
Copied person's address: New City

代码解析

在上述代码中,copiedPerson 是通过浅拷贝创建的。它复制了 originalPersonname 字段和 address 引用。由于 address 是引用类型,两个 Person 对象的 address 字段指向同一个 Address 对象。因此,当修改 copiedPerson 的地址时,originalPerson 的地址也会发生变化。

二、深拷贝

深拷贝是指创建一个新对象,并将原对象的字段值复制到新对象中。如果字段是引用类型,则递归地创建该引用对象的深拷贝,确保新对象与原对象在内存中完全独立。

示例代码

class Address implements Cloneable {
    String street;
    String city;

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

    @Override
    public Address clone() {
        try {
            return (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

class Person implements Cloneable {
    String name;
    Address address;

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

    @Override
    public Person clone() {
        try {
            Person cloned = (Person) super.clone();
            cloned.address = address.clone();
            return cloned;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

public class DeepCopyExample {
    public static void main(String[] args) {
        Address originalAddress = new Address("123 Main St", "Anytown");
        Person originalPerson = new Person("John Doe", originalAddress);

        // 深拷贝
        Person copiedPerson = originalPerson.clone();

        // 修改拷贝对象的地址
        copiedPerson.address.city = "New City";

        System.out.println("Original person's address: " + originalPerson.address.city);
        System.out.println("Copied person's address: " + copiedPerson.address.city);
    }
}

输出结果

Original person's address: Anytown
Copied person's address: New City

代码解析

在上述代码中,copiedPerson 是通过深拷贝创建的。它复制了 originalPersonname 字段,并创建了 address 对象的深拷贝。因此,两个 Person 对象的 address 字段指向不同的 Address 对象。修改 copiedPerson 的地址不会影响 originalPerson 的地址。

三、总结

浅拷贝只复制对象的直接字段,对于引用类型字段,复制的是引用,因此原对象和拷贝对象的引用字段指向同一个对象。深拷贝则递归地复制对象及其引用的所有对象,确保原对象和拷贝对象完全独立。在实际开发中,根据需求选择合适的拷贝方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java皇帝

有帮助就赏点吧,博主点杯水喝喝

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

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

打赏作者

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

抵扣说明:

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

余额充值