绝对一看就懂!深拷贝和浅拷贝

通过下面一个实例了解深拷贝与浅拷贝

Person 中有两个成员变量,分别是 name 和 age, name 是 String 类型, age 是 int 类型。代码非常简单:

public class Person implements Cloneable {
    privatint age;
    private String name;
    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    } 
    public Person() {
    }
    public int getAge() {
        return age;
    }
    public String getName() {
        return name;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
}

由于 age 是基本数据类型,那么对它的拷贝没有什么疑议,直接将一个 4 字节的整数值拷贝过来就行。但是 name是 String 类型的, 它只是一个引用, 指向一个真正的 String 对象,那么对它的拷贝有两种方式: 直接将原对象中的name 的引用值拷贝给新对象的 name 字段, 或者是根据原 Person 对象中的 name 指向的字符串对象创建一个新的相同的字符串对象,将这个新字符串对象的引用赋给新拷贝的 Person 对象的 name 字段。这两种拷贝方式分别
叫做浅拷贝和深拷贝。深拷贝和浅拷贝的原理如下图所示:
在这里插入图片描述下面通过代码进行验证。如果两个 Person 对象的 name 的地址值相同, 说明两个对象的 name 都指向同一个String 对象,也就是浅拷贝, 而如果两个对象的 name 的地址值不同, 那么就说明指向不同的 String 对象, 也就是在拷贝 Person 对象的时候, 同时拷贝了 name 引用的 String 对象, 也就是深拷贝。验证代码如下:

    Person p = new Person(23, "zhang");
    Person p1 = (Person) p.clone();
    String result = p.getName() == p1.getName()
            ? "clone 是浅拷贝的" : "clone 是深拷贝的";
    System.out.println(result);

打印结果为:

   clone 是浅拷贝的

所以,clone 方法执行的是浅拷贝, 在编写程序时要注意这个细节。

如何进行深拷贝:
要实现 Cloneable 接口,实现 clone方法,并且在 clone 方法内部,把该对象引用的其他对象也要 clone 一份,这就要求这个被引用的对象必须也要实现
Cloneable 接口并且实现 clone 方法。那么,按照上面的结论,实现以下代码 Body 类组合了 Head 类,要想深拷贝Body 类,必须在 Body 类的 clone 方法中将 Head 类也要拷贝一份。代码如下:

 static class Body implements Cloneable {
        public Head head;
        public Body() {
        }
        public Body(Head head) {
            this.head = head;
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Body newBody = (Body) super.clone();
            newBody.head = (Head) head.clone();
            return newBody;
        }
    }
    static class Head implements Cloneable {
        public Face face;
        public Head() {
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        Body body = new Body(new Head(new Face()));
        Body body1 = (Body) body.clone();
        System.out.println("body == body1 : " + (body == body1));
        System.out.println("body.head == body1.head : " + (body.head == body1.head));
    }

打印结果为:

 body == body1 : false
 body.head == body1.head : false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值