说说深拷贝和浅拷贝?

460 阅读2分钟

在Java中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是对象复制的两种方式,它们在处理对象引用时有不同的行为。以下是它们的主要区别和示例:

1. 浅拷贝(Shallow Copy)

  • 定义:浅拷贝创建一个新对象,但只是复制对象的基本数据类型值和对象引用,而不是引用的对象本身。
  • 行为:如果原对象包含其他对象的引用,那么浅拷贝后的新对象将引用同一个对象,而不是创建新的对象。

示例

class Person {
    String name;
    Address address;

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

    // 浅拷贝方法
    public Person shallowCopy() {
        return new Person(this.name, this.address);
    }
}

class Address {
    String city;

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

public class Main {
    public static void main(String[] args) {
        Address address = new Address("New York");
        Person person1 = new Person("Alice", address);

        // 浅拷贝
        Person person2 = person1.shallowCopy();

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

        // 输出结果
        System.out.println(person1.address.city); // 输出 "Los Angeles"
        System.out.println(person2.address.city); // 输出 "Los Angeles"
    }
}

在这个示例中,person1 和 person2 都引用了同一个 Address 对象,因此修改 person2 的地址也会影响 person1 的地址。

2. 深拷贝(Deep Copy)

  • 定义:深拷贝不仅创建一个新对象,还会递归地创建所有引用对象的新副本。
  • 行为:如果原对象包含其他对象的引用,那么深拷贝后的新对象将引用新的对象,而不是共享同一个对象。

示例

class Person {
    String name;
    Address address;

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

    // 深拷贝方法
    public Person deepCopy() {
        Address newAddress = new Address(this.address.city);
        return new Person(this.name, newAddress);
    }
}

class Address {
    String city;

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

public class Main {
    public static void main(String[] args) {
        Address address = new Address("New York");
        Person person1 = new Person("Alice", address);

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

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

        // 输出结果
        System.out.println(person1.address.city); // 输出 "New York"
        System.out.println(person2.address.city); // 输出 "Los Angeles"
    }
}

在这个示例中,person1 和 person2 引用了不同的 Address 对象,因此修改 person2 的地址不会影响 person1 的地址。

总结

  • 浅拷贝:只复制对象的基本数据类型值和对象引用,不创建新的引用对象。
  • 深拷贝:不仅复制对象的基本数据类型值和对象引用,还会递归地创建所有引用对象的新副本。