【Java基础】Java拷贝

251 阅读2分钟

我是 啤酒就辣条,一个Java。
学而时习之,不亦说乎?希望通过博客的形式,总结、分享,梳理自己、帮助他人。
另外,啤酒就辣条,味道不错哦~

浅拷贝和深拷贝

浅拷贝是将基本数据类型复制一份,共用引用类型的数据

深拷贝在堆中完全创建一个新的对象,基本数据类型和引用数据类型都进行复制。

代码示例

浅拷贝

首先创建两个类 Father 和 Child

public class Father implements Cloneable{
    private String name;
    private Child child;
    // 此处省略get、set方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Child {
    private String name;
    // 此处省略get、set方法
}
public class CopyTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Father father1 = new Father();
        father1.setName("pjjlt");
        Child child = new Child();
        child.setName("child");
        father1.setChild(child);
        Father father2 = (Father) father1.clone();
        System.out.println("father1的名字是:"+father1.getName());
        System.out.println("father2的名字是:"+father2.getName());
        System.out.println("father1 Child的名字是:"+father1.getChild().getName());
        System.out.println("father2 Child的名字是:"+father2.getChild().getName());
        System.out.println("father1和father2的hashCode:"+(father1.hashCode() == father2.hashCode()));
        System.out.println("两个Child的hashCode:"+(father1.getChild().hashCode() == father2.getChild().hashCode()));
        father1.setName("啤酒就辣条");
        father1.getChild().setName("孩子");
        System.out.println("*******************更新之后*******************");
        System.out.println("father1的名字是:"+father1.getName());
        System.out.println("father2的名字是:"+father2.getName());
        System.out.println("father1 Child的名字是:"+father1.getChild().getName());
        System.out.println("father2 Child的名字是:"+father2.getChild().getName());
        System.out.println("father1和father2的hashCode:"+(father1.hashCode() == father2.hashCode()));
        System.out.println("两个Child的hashCode:"+(father1.getChild().hashCode() == father2.getChild().hashCode()));
    }
}
// 输出结果
father1的名字是:pjjlt
father2的名字是:pjjlt
father1 Child的名字是:child
father2 Child的名字是:child
father1和father2的hashCode:false
两个Child的hashCode:true
*******************更新之后*******************
father1的名字是:啤酒就辣条
father2的名字是:pjjlt
father1 Child的名字是:孩子
father2 Child的名字是:孩子
father1和father2的hashCode:false
两个Child的hashCode:true

由此可见,father1和father2基本数据类型复制了,而引用数据类型公用了。

深拷贝

下面单纯修改Father和Child类,再打印看看。

public class Father implements Cloneable{
    private String name;
    private Child child;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Father cloneFather = (Father) super.clone();
        cloneFather.setChild((Child) this.child.clone());
        return cloneFather;
    }
}
public class Child implements Cloneable{
    private String name;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// 打印结果
father1的名字是:pjjlt
father2的名字是:pjjlt
father1 Child的名字是:child
father2 Child的名字是:child
father1和father2的hashCode:false
两个Child的hashCode:false
*******************更新之后*******************
father1的名字是:啤酒就辣条
father2的名字是:pjjlt
father1 Child的名字是:孩子
father2 Child的名字是:child
father1和father2的hashCode:false
两个Child的hashCode:false

由此可见,father1和father2的基本数据类型引用数据类型都进行复制了。