如何完美解答面试问题——深拷贝和浅拷贝的区别

大家好,我是孤焰。今天要谈一谈在面试过程中可能被面试官提到的一个问题——深拷贝和浅拷贝的区别?
由于我也是刚刚学习编程的小白,所以此篇博文将参考了多篇博文,最后总结而成。
最近由于多门考试临近,所以博文更新速度可能会慢一些,希望大家谅解。

 在 Java 中,除了基本数据类型(元类型)之外,还存在 类的实例对象 这个引用数据类型。而一般使用 = 号做赋值操作的时候。对于基本数据类型,实际上是拷贝的它的值,但是对于对象而言,其实赋值的只是这个对象的引用,将原对象的引用传递过去,他们实际上还是指向的同一个对象。

1.浅拷贝

浅拷贝:浅拷贝时被复制对象中的成员变量若为引用数据类型,那么只将此成员对象的引用复制,而不重新实例新的成员对象。换言之,被复制的对象的所有的变量都与原对象有相同的值,而所有的引用对象仍然指向原来的对象。

 代码举例如下:

//测试类
public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        //原始对象
        ShallowCopy shallowCopy = new ShallowCopy();
        shallowCopy.setBaseType(1);
        shallowCopy.setObjectClass("我是孤焰");

        //复制对象
        ShallowCopy shallowCopy2 = (ShallowCopy) shallowCopy.clone();

        shallowCopy.setBaseType(2);
        shallowCopy.setObjectClass("我是修改后的孤焰");

        System.out.println("原始对象的基础类型值为:" + shallowCopy.getBaseType());
        System.out.println("原始对象的引用类型的地址为:" + shallowCopy.getObjectClass());

        System.out.println();

        System.out.println("复制对象的基础类型值为:" + shallowCopy2.getBaseType());
        System.out.println("复制对象的引用类型的地址为:" + shallowCopy2.getObjectClass());
    }
}

class ObjectClass {
    private String content;

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "ObjectClass{" +
                "content='" + content + '\'' +
                '}';
    }
}

class ShallowCopy implements Cloneable {
    private int baseType;
    private ObjectClass objectClass;

    public ShallowCopy() {
        objectClass = new ObjectClass();
    }

    public int getBaseType() {
        return baseType;
    }

    public void setBaseType(int baseType) {
        this.baseType = baseType;
    }

    public ObjectClass getObjectClass() {
        return objectClass;
    }

    public void setObjectClass(String value) {
        this.objectClass.setContent(value);
    }

    //浅拷贝的clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

 程序运行结果为:
在这里插入图片描述

 可以发现在对shallowCopy对象浅拷贝之后修改了shallowCopy对象中的引用类型对象的值,然后复制对象shallowCopy2中的引用类型对象的值也改变了,那么就证明了浅拷贝仅仅是将对象中引用类型变量地址复制,而不是重新实例化一个新的引用类型对象。

2.深拷贝

深拷贝:深拷贝时会将被复制对象中的引用数据类型的成员变量的副本以及基本数据类型的变量的值赋值给新的对象。

 对上个例子进行简单改动后,代码如下:

//测试类
public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        //原始对象
        ShallowCopy shallowCopy = new ShallowCopy();
        shallowCopy.setBaseType(1);
        shallowCopy.setObjectClass("我是孤焰");

        //复制对象
        ShallowCopy shallowCopy2 = (ShallowCopy) shallowCopy.clone();

        shallowCopy.setBaseType(2);
        shallowCopy.setObjectClass("我是修改后的孤焰");

        System.out.println("原始对象的基础类型值为:" + shallowCopy.getBaseType());
        System.out.println("原始对象的引用类型的值为:" + shallowCopy.getObjectClass());

        System.out.println();

        System.out.println("复制对象的基础类型值为:" + shallowCopy2.getBaseType());
        System.out.println("复制对象的引用类型的值为:" + shallowCopy2.getObjectClass());
    }
}

class ObjectClass implements Cloneable {
    private String content;

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "ObjectClass{" +
                "content='" + content + '\'' +
                '}';
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class ShallowCopy implements Cloneable {
    private int baseType;
    private ObjectClass objectClass;

    public ShallowCopy() {
        objectClass = new ObjectClass();
    }

    public int getBaseType() {
        return baseType;
    }

    public void setBaseType(int baseType) {
        this.baseType = baseType;
    }

    public ObjectClass getObjectClass() {
        return objectClass;
    }

    public void setObjectClass(String value) {
        this.objectClass.setContent(value);
    }

    //深拷贝的clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        ShallowCopy shallowCopy = (ShallowCopy) super.clone();
        shallowCopy.objectClass = (ObjectClass) this.objectClass.clone();
        return shallowCopy;
    }
}

 程序运行结果为:
在这里插入图片描述

 将clone()方法更改为深拷贝之后,可以发现现在shallowCopy对象中引用类型的值被修改并没有影响到shallowCopy2对象中引用类型的值。

3.总结

 通过上面举例,相信大家也可以分清深拷贝和浅拷贝的区别了,下面用两幅图来总结他们的区别。
在这里插入图片描述
浅拷贝是拷贝基本类型变量的值和引用类型变量的地址值。

在这里插入图片描述
深拷贝会拷贝基本类型变量的值和引用类型变量的实例化。

4.最后

都看到最后了,求求大家点个赞再走吧!你的支持是博主创作的最大动力。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值