深拷贝与浅拷贝

再说深拷贝和浅拷贝之前先讲一个概念,引用拷贝和对象拷贝

经常有人会把引用拷贝理解为浅拷贝

1    Dog dog1 = new Dog();
2    Dog dog2 = dog1;

这其实只是一个赋值操作,把dog1的值赋值给了dog2,他们指向的其实是同一个对象,这种情况属于引用拷贝,通常意义上的深拷贝和浅拷贝都指的是对象拷贝

深拷贝和浅拷贝的理解

浅拷贝:

原型对象和复制出来的新对象,他们的引用类型的属性如果地址值相同则是浅拷贝

浅拷贝需要实现Cloneable接口,Cloneable其实是个空接口,相当于一个标记(和Serializable接口一样),重写clone方法,里面调用父类的clone方法即可(调用的是Object的clone方法)。

 1public class Dog implements Cloneable {
2
3    /**
4     * 年龄(基本类型)
5     */

6    private int age;
7
8    /**
9     * 主人(引用类型)
10     */

11    private DogOwner owner;
12
13    public Dog clone() throws CloneNotSupportedException {
14        return (Dog)super.clone();
15    }
16}

通过调用clone方法拷贝的对象你会发现是重新创建了一个对象,但是对象里面的引用类型的熟悉指向的还是同一个地址(dog1和dog2指向的地址不同,dog1和dog2中的dogOwner指向的地址相同)

1        Dog dog1 = new Dog();
2        dog1.setAge(5);
3        DogOwner dogOwner = new DogOwner();
4        dog1.setOwner(dogOwner);
5        Dog dog2 = (Dog) dog1.clone();
6        System.out.println("dog1是否等于dog2: "+(dog1 == dog2));
7        System.out.println("dog1中的owner是否等于dog2中的owner: "+(dog1.getOwner() == dog2.getOwner()));

深拷贝:

原型对象和复制出来的新对象,他们的所有属性的地址值都是不同的

深拷贝的实现方式有很多种,常见方式就是通过序列化和反序列化、转json字符串在转成对象(其实原理类似)
我们以序列化为例:首先Dog类和DogOwner类都实现Serializable接口,然后通过序列化和反序列化操作得到新的对象,我们会发现dog对象和里面的引用类型的属性指向的地址都不同,此时就是完成了深拷贝

 1        Dog dog1 = new Dog();
2        dog1.setAge(5);
3        DogOwner dogOwner = new DogOwner();
4        dog1.setOwner(dogOwner);
5
6         //将对象序列化到二进制流
7        ByteArrayOutputStream bos = new ByteArrayOutputStream();
8        ObjectOutputStream oos = new ObjectOutputStream(bos);
9        oos.writeObject(dog1);
10
11         //从二进制流中读出产生的新对象
12        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
13        ObjectInputStream ois = new ObjectInputStream(bis);
14        Dog dog2 = (Dog)ois.readObject();
15
16        System.out.println("dog1是否等于dog2: " + (dog1 == dog2));
17        System.out.println("dog1中的owner是否等于dog2中的owner: " + (dog1.getOwner() == dog2.getOwner()));

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值