对象的深拷贝和浅拷贝浅析:对象中有List

目的

本文主要由实例的结果去分析深浅拷贝的不同,然后去理解深浅拷贝。对比深浅拷贝的结果,通过查看属性listString 和listUser 的值确定拷贝是否成功。

浅拷贝类

public class UserShallowClone implements Cloneable{
    String name;
    int age;
    public List<String> listString = new ArrayList();
    public List<UserShallowClone> listUser = new ArrayList();

    public UserShallowClone(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected UserShallowClone clone(){
        try {
            return (UserShallowClone)super.clone();
        }catch (Exception e){
            return null;
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

简要分析:
实现了Cloneable接口,重写clone方法,次方法是native本地方法看不到源码。
核心方法只有super.clone();

深拷贝类

public class UserDeepClone implements Cloneable{
    String name;
    int age;
    public List<String> listString = new ArrayList();
    public List<UserDeepClone> listUser = new ArrayList();

    public UserDeepClone(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected UserDeepClone clone(){
        UserDeepClone d = null;
        try {
             d = (UserDeepClone) super.clone();
             d.listUser = new ArrayList<>();
             for(UserDeepClone u:listUser){
                 d.listUser.add(u.clone());
             }

        }catch (Exception e){
        }
        return d;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

简要分析:
此深拷贝类与浅拷贝类不同是对属性listUser 又做了一次克隆。作为对比listString 没有做克隆

测试类

public class CloneMain {

    public static void main(String[] args) {

        System.out.println("浅克隆-----------------------------------");
        System.out.println("克隆前初始化");
        UserShallowClone u = new UserShallowClone("原始人", 21);
        u.listString.add("aaa");
        u.listUser.add(new UserShallowClone("listUser1", 21));

        System.out.println(u.listString);
        System.out.println(u.listUser.size());
        for (UserShallowClone d : u.listUser) {
            System.out.println(d.getName() + d.getAge());
        }

        System.out.println("克隆后-----------------------------------");
        UserShallowClone usc = u.clone();

        usc.listString.add("bbb");
        usc.listUser.add(new UserShallowClone("listUser2", 21));
        usc.listUser.add(new UserShallowClone("listUser3", 21));
        System.out.println(usc.listString);
        System.out.println(usc.listUser.size());
        for (UserShallowClone d : usc.listUser) {
            System.out.println(d.getName() + d.getAge());
        }

        System.out.println("验证-----------------------------------");
        System.out.println(u.listString);
        System.out.println(u.listUser.size());
        for (UserShallowClone d : u.listUser) {
            System.out.println(d.getName() + d.getAge());
        }

        System.out.println("深克隆-----------------------------------");
        UserDeepClone ud = new UserDeepClone("原始人", 21);
        System.out.println("克隆前初始化");
        ud.listString.add("aaa");
        ud.listUser.add(new UserDeepClone("listUser1", 21));
        System.out.println(ud.listString);
        System.out.println(ud.listUser.size());
        for (UserDeepClone d : ud.listUser) {
            System.out.println(d.getName() + d.getAge());
        }

        System.out.println("克隆后");
        UserDeepClone udc = ud.clone();
        udc.listString.add("bbb");
        udc.listUser.add(new UserDeepClone("listUser2", 21));
        udc.listUser.add(new UserDeepClone("listUser3", 21));
        System.out.println(udc.listString);
        System.out.println(udc.listUser.size());
        for (UserDeepClone d : udc.listUser) {
            System.out.println(d.getName() + d.getAge());
        }

        System.out.println("验证-----------------------------------");
        System.out.println(ud.listString);
        System.out.println(ud.listUser.size());
        for (UserDeepClone d : ud.listUser) {
            System.out.println(d.getName() + d.getAge());
        }

    }
}

测试结果

浅克隆-----------------------------------
克隆前初始化
[aaa]
1
listUser121
克隆后-----------------------------------
[aaa, bbb]
3
listUser121
listUser221
listUser321
验证-----------------------------------
[aaa, bbb]
3
listUser121
listUser221
listUser321


深克隆-----------------------------------
克隆前初始化
[aaa]
1
listUser121
克隆后
[aaa, bbb]
3
listUser121
listUser221
listUser321
验证-----------------------------------
[aaa, bbb]
1
listUser121

重点来了,结果分析
1.深拷贝和浅拷贝之前都先对对象初始化,初始化值是一样的。
listString的值是aaa
listUser的用户名是listUser1,年龄是21
2.然后进行深浅拷贝的方法clone调用实现克隆
3.改变克隆后的listString和listUser的值,listString添加一个值bbb。listUser添加两个值
4.最后验证原来的值受影响了没

浅拷贝结果,分析原对象内的值改变了没

发现拷贝之前的listString的值多了个bbb,变成[aaa, bbb]
拷贝之前的listUser的值也变了,多了两个,结果如下:
3
listUser121
listUser221
listUser321

深拷贝结果,分析原对象内的值改变了没

listString值也变了[aaa, bbb],这是正常的,因为没做克隆。所以拷贝后实际引用的是同一个对象。克隆后的变了,原来的就也变了。
但是克隆后的listUser的值和克隆前的确不一样,说明成功拷贝,且不影响原来的,达到效果。

如果有帮助到你,请点个赞。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值