深拷贝和浅拷贝是什么?

浅拷贝

浅拷贝:是指将一个对象复制到另一个变量中,但是只复制对象的地址,而不是对象本身。

也就是说,原始对象、和复制对象实际上是共享同一个内存地址的,如果修改了复制对象,原始对象也会改变。

如下图所示:

深拷贝和浅拷贝是什么?-mikechen

当引用对象的成员属性改变时,原型对象和拷贝对象都会发生改变。

看一个例子:

public class CopyTest {
    static class Address {
        String city;

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

    static  class Person implements Cloneable {
        String name;
        Address address;

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

        // 实现浅拷贝
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address("New York");
        Person person1 = new Person("John", address);
        Person person2 = (Person) person1.clone();

        System.out.println("Person1 Address: " + person1.address.city); // 输出: New York
        System.out.println("Person2 Address: " + person2.address.city); // 输出: New York

        person2.address.city = "Los Angeles";
        System.out.println("After changing person2's address:");
        System.out.println("Person1 Address: " + person1.address.city); // 输出: Los Angeles
        System.out.println("Person2 Address: " + person2.address.city); // 输出: Los Angeles
    }


}

输出为:

Person1 Address: New York
Person2 Address: New York
After changing person2's address:
Person1 Address: Los Angeles
Person2 Address: Los Angeles

改变 person2address 会为:”Los Angeles“影响 person1,因为它们共享同一个 Address 对象的引用。

 

深拷贝

深拷贝会创建一个全新的对象,并将原始对象中的所有属性、或元素都复制到新的对象中。

这个新对象不仅复制原始对象的所有非静态字段值,还会递归地复制所有引用类型字段所指向的对象,确保新对象和原对象之间没有共享的可变对象。

深拷贝和浅拷贝是什么?-mikechen

如果我们修改复制对象中的属性或元素,原始对象中对应的属性或元素不会受到影响。

看一个例子:

package com.mikechen.java.basis;

public class ShenCopyTest {
    static class Address implements Cloneable {
        String city;

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

        // 实现深拷贝
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return new Address(this.city);
        }
    }

    static class Person implements Cloneable {
        String name;
        Address address;

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

        // 实现深拷贝
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Person clonedPerson = (Person) super.clone();
            clonedPerson.address = (Address) this.address.clone();
            return clonedPerson;
        }
    }

        public static void main(String[] args) throws CloneNotSupportedException {
            Address address = new Address("New York");
            Person person1 = new Person("John", address);
            Person person2 = (Person) person1.clone();

            System.out.println("Person1 Address: " + person1.address.city); // 输出: New York
            System.out.println("Person2 Address: " + person2.address.city); // 输出: New York

            person2.address.city = "Los Angeles";
            System.out.println("After changing person2's address:");
            System.out.println("Person1 Address: " + person1.address.city); // 输出: New York
            System.out.println("Person2 Address: " + person2.address.city); // 输出: Los Angeles
        }

}

输出:

Person1 Address: New York
Person2 Address: New York
After changing person2's address:
Person1 Address: New York
Person2 Address: Los Angeles

Person 类的 clone 方法不仅调用 super.clone(),还显式地调用了 address 对象的 clone 方法,实现了深拷贝。

mikechen

mikechen睿哥,10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复架构即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

评论交流
    说说你的看法