Java技术栈.基础篇—浅拷贝与深拷贝

浅拷贝与深拷贝是什么

浅拷贝和深拷贝本质都是对一个已有引用对象进行拷贝操作,但二者存在一定的区别。

在 Java 中,数据类型分为 基本数据类型(元类型)和 引用数据类型。而一般使用 『 = 』号做赋值操作的时候,对于基本数据类型,实际上是拷贝的它的值,但是对于引用数据类型而言,其实将原对象的引用传递过去,它们实际是指向同一个对象。

浅拷贝和深拷贝的区别就在于:在拷贝某个对象的时候,如果只对基本数据类型的成员变量进行了值的拷贝,而对引用数据类型的成员变量只是进行了引用的传递,而没有为其创建一个新的对象,是浅拷贝;反之,在对引用数据类型的成员变量进行拷贝的时候,为其创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝

所以浅拷贝和深拷贝的本质是 对某个对象的引用数据类型的成员变量的不同操作而已。

浅拷贝

对基本数据类型进行值传递,对引用数据类型进行引用传递的拷贝。
在这里插入图片描述

深拷贝

对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容。

在这里插入图片描述

Java中的clone方法

在 Java 中,所有的类都继承自 Object 。在 Object 中有一个 clone() 方法,浅拷贝和深拷贝 需要实现 clone() 方法,来完成操作。
在这里插入图片描述

通过注释我们知道所有调用 clone() 方法的对象,都必须实现 Cloneable 接口,否则将抛 CloneNotSupportedException 异常。

浅拷贝示例

 private class BoyObject implements Cloneable{
        public String name;
        public int age;
        public GirlFriend girlFriend;

        @Override
        public Object clone(){
            try {
                return super.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println(e);
            }
            return null;
        }


    }

    private class GirlFriend implements Cloneable{
        public String name;
        public int age;

        @Override
        public Object clone(){
            try {
                return super.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println(e);
            }
            return null;
        }
    }

    public void cloneTest() {
        BoyObject boyObject = new BoyObject();
        boyObject.girlFriend = new GirlFriend();
        boyObject.name = "xiaoqiang";
        boyObject.age = 18;
        boyObject.girlFriend.name = "xiaoli";
        boyObject.girlFriend.age = 18;

        BoyObject cloneObject = (BoyObject)boyObject.clone();

        System.out.println("boyObject hashcode=" + boyObject.hashCode());
        System.out.println("boyObject name=" + boyObject.name);
        System.out.println("boyObject age=" + boyObject.age);
        System.out.println("boyObject girlFriend hashcode=" + boyObject.girlFriend.hashCode());

        System.out.println("cloneObject hashcode=" + cloneObject.hashCode());
        System.out.println("cloneObject name=" + cloneObject.name);
        System.out.println("cloneObject age=" + cloneObject.age);
        System.out.println("cloneObject girlFriend hashcode=" + cloneObject.girlFriend.hashCode());
    }

运行测试方法,输出如下:

boyObject hashcode=935044096
boyObject name=xiaoqiang
boyObject age=18
boyObject girlFriend hashcode=396180261

cloneObject hashcode=625576447
cloneObject name=xiaoqiang
cloneObject age=18
cloneObject girlFriend hashcode=396180261

由上可知,boyObject 与 cloneObject 的hashcode不同,说明 由boyObject.clone() 得到了一个新的 BoyObject 对象。但这是一次浅拷贝,因为 boyObject.girlFriend .hashcode 与 cloneObject.girlFriend.hashcode 一致,说明在boyObject 拷贝时girlFriend 只是进行了应用传递,而没有创建一个新的 GirlFriend 对象。boyObject 与 cloneObject 的 girlFriend 属性指向同一个对象。

深拷贝实例

深拷贝只做以下改动,其他保持不变:

 private class BoyObject implements Cloneable{
        public String name;
        public int age;
        public GirlFriend girlFriend;

        @Override
        public Object clone(){
            try {
                BoyObject cloneObject = (BoyObject)super.clone();
                cloneObject.girlFriend = (GirlFriend)this.girlFriend.clone();
                return cloneObject;
            } catch (CloneNotSupportedException e) {
                System.out.println(e);
            }
            return null;
        }
    }

重新运行后输出如下:

boyObject hashcode=935044096
boyObject name=xiaoqiang
boyObject age=18
boyObject girlFriend hashcode=396180261

cloneObject hashcode=625576447
cloneObject name=xiaoqiang
cloneObject age=18
cloneObject girlFriend hashcode=1560911714

由上可知,boyObject.girlFriend .hashcode 与 cloneObject.girlFriend.hashcode 不一致,说明boyObject.clone()方法在拷贝时创建了一个新的 GirlFriend 对象赋值给了cloneObject的 girlFriend属性,是深拷贝。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值