【Java深拷贝和浅拷贝】

Java深拷贝和浅拷贝

深拷贝和浅拷贝都是对象拷贝

浅拷贝

:在进行对象拷贝时,仅仅只拷了一层对象,而其子对象则不会拷贝,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象

public class ShallowCopy {
    public static void main(String[] args) {
        Parents parents = new Parents();
        parents.setName("kong");
        parents.setAge("34");

        Child child = new Child();
        child.setUsername("Dream");
        child.setId(1);
        child.setParents(parents);

        Child child2 = (Child) child.clone();
        System.out.println("拷贝后");
        System.out.println(child2.getUsername());
        System.out.println(child2.getId());
        System.out.println(child2.getParents().getName());
        System.out.println(child2.getParents().getAge());
        System.out.println("修改父母的信息后-------------");

        // 修改父母的信息
        parents.setName("Jam");
        System.out.println(child.getParents().getName());
        System.out.println(child2.getParents().getName());

    }

}
class Parents implements Cloneable{
    private String name;
    private String age;

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Parents{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}
class Child implements Cloneable{
    private String username;
    private int id;
    private Parents parents;

    public Parents getParents() {
        return parents;
    }

    public void setParents(Parents parents) {
        this.parents = parents;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    //浅拷贝
    @Override
    public Child clone() {
        try {
            return (Child) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

远行结果:
远行结果
分析:以上代码可以看出,child和child2不是同一个对象,但是当修改父母的信息时,再输出Child类的parents属性值时,两个不同的对象的parents属性值都被修改了。
画图分析:
在这里插入图片描述

深拷贝

深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。深拷贝把要复制的对象所引用的对象都复制了一遍。
第一种方法:

package Copy;

public class ShallowCopy {
    public static void main(String[] args) throws CloneNotSupportedException {
        Parents parents = new Parents();
        parents.setName("kong");
        parents.setAge("34");

        Child child = new Child();
        child.setUsername("Dream");
        child.setId(1);
        child.setParents(parents);

        Child child2 = (Child) child.clone();
        System.out.println("拷贝后");
        System.out.println(child2.getUsername());
        System.out.println(child2.getId());
        System.out.println(child2.getParents().getName());
        System.out.println(child2.getParents().getAge());
        System.out.println("修改父母的信息后-------------");

        // 修改父母的信息
        parents.setName("Jam");
        System.out.println(child.getParents().getName());
        System.out.println(child2.getParents().getName());

    }

}
class Parents implements Cloneable{
    private String name;
    private String age;

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Parents{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    @Override
    public Parents clone() {
        try {
            // TODO: copy mutable state here, so the clone can't change the internals of the original
            return (Parents) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
class Child implements Cloneable{
    private String username;
    private int id;
    private Parents parents;

    public Parents getParents() {
        return parents;
    }

    public void setParents(Parents parents) {
        this.parents = parents;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

//    @Override
//    public Child clone() {
//        try {
//            // TODO: copy mutable state here, so the clone can't change the internals of the original
//            return (Child) super.clone();
//        } catch (CloneNotSupportedException e) {
//            throw new AssertionError();
//        }
//    }
    public Object clone() throws CloneNotSupportedException {
        // 改为深复制
        Child child2 = (Child) super.clone();
        // 本来是浅复制,现在将Parents对象复制一份并重新set进来
        child2.setParents(child2.getParents().clone());
        return child2;
    }
}

远行结果:
在这里插入图片描述
分析:两个引用child和child2指向不同的两个对象,两个引用child和child2中的两个parents引用指向的是两个对象,但对parents对象的修改只能影响child2对象,所以说是深拷贝。
画图分析:
在这里插入图片描述

第二种方法:类实现Serializable接口
代码如下:

package Copy;

import java.io.*;

public class ShallowCopy {
    public static void main(String[] args) throws Exception {
        Parents parents = new Parents();
        parents.setName("kong");
        parents.setAge("34");
        Child child = new Child();
        child.setUsername("Dream");
        child.setId(1);
        child.setParents(parents);

        Child child2 = (Child) child.deepClone();
        System.out.println("拷贝后");
        System.out.println(child2.getUsername());
        System.out.println(child2.getId());
        System.out.println(child2.getParents().getName());
        System.out.println(child2.getParents().getAge());
        System.out.println("修改父母的信息后-------------");

        // 修改父母的信息
        parents.setName("Jam");
        System.out.println(child.getParents().getName());
        System.out.println(child2.getParents().getName());

    }

}
class Parents implements Serializable {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Parents{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

//    @Override
//    public Parents clone() {
//        try {
//            // TODO: copy mutable state here, so the clone can't change the internals of the original
//            return (Parents) super.clone();
//        } catch (CloneNotSupportedException e) {
//            throw new AssertionError();
//        }
//    }
}
class Child implements Serializable{
    private String username;
    private int id;
    private Parents parents;

    public Parents getParents() {
        return parents;
    }

    public void setParents(Parents parents) {
        this.parents = parents;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

//    @Override
//    public Child clone() {
//        try {
//            // TODO: copy mutable state here, so the clone can't change the internals of the original
//            return (Child) super.clone();
//        } catch (CloneNotSupportedException e) {
//            throw new AssertionError();
//        }
//    }
//    public Object clone() throws CloneNotSupportedException {
//        // 改为深复制
//        Child child2 = (Child) super.clone();
//        // 本来是浅复制,现在将Parents对象复制一份并重新set进来
//        child2.setParents(child2.getParents().clone());
//        return child2;
//    }
    public Object deepClone() throws Exception {
        // 序列化
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);

        oos.writeObject(this);

        // 反序列化
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }
}

远行结果:

在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值