DaiXT:深克隆和浅克隆浅析

在Java语言中,通过覆盖Object类的clone()方法可以实现浅克隆。

1、浅克隆
在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。

2、深克隆
在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。

在Java语言中,如果需要实现深克隆,可以通过覆盖Object类的clone()方法实现,也可以通过序列化(Serialization)等方式来实现。(如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。)

序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。

浅克隆代码示例

student

public class Student implements Cloneable{
    private int number;
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
    //重写Object类下面clone()方法
    public Student clone(){
        Student stu = null;
        try {
            stu = (Student)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return stu;
    }
}

Adrress

package JavaBean.CloneDemo.ShallowClone;

public class Address {
    private  String  add;

    public String getAdd() {
        return add;
    }

    public void setAdd(String add) {
        this.add = add;
    }
}

主函数

package Main;
import JavaBean.CloneDemo.ShallowClone.Address;
import JavaBean.CloneDemo.ShallowClone.Student;

public class CloneMain {
    public static void main(String[] args)  {
        System.out.println("----------------------浅克隆-----------------------------");
//        浅克隆
        Student stu = new Student();
        stu.setNumber(123);
        Student stu2 = stu.clone();
        System.out.println("学生1: "+stu.getNumber()+" - 引用的哈希编码"+stu.hashCode());
        System.out.println("学生2: "+stu2.getNumber()+" - 引用的哈希编码"+stu2.hashCode());

        stu2.setNumber(1189);

        System.out.println("学生1: "+stu.getNumber()+" - 引用的哈希编码"+stu.hashCode());
        System.out.println("学生2: "+stu2.getNumber()+" - 引用的哈希编码"+stu2.hashCode());


        Address addr1 = new Address();
        Student stu3 = new Student();
        addr1.setAdd("北京市");
        stu3.setNumber(123);
        stu3.setAddress(addr1);
        Student stu4 = stu3.clone();

        System.out.println("学生1: "+stu3.getNumber()+"地址"+stu3.getAddress().getAdd()+" - 地址的哈希编码"+addr1.hashCode()+" - 引用的哈希编码值为"+stu3.hashCode());
        System.out.println("学生2: "+stu4.getNumber()+"地址"+stu4.getAddress().getAdd()+" - 地址的哈希编码"+addr1.hashCode()+" - 引用的哈希编码值为"+stu4.hashCode());

        addr1.setAdd("河南省");

        System.out.println("学生1: "+stu3.getNumber()+"地址"+stu3.getAddress().getAdd()+" - 地址的哈希编码"+addr1.hashCode()+" - 引用的哈希编码值为"+stu3.hashCode());
        System.out.println("学生2: "+stu4.getNumber()+"地址"+stu4.getAddress().getAdd()+" - 地址的哈希编码"+addr1.hashCode()+" - 引用的哈希编码值为"+stu4.hashCode());

    }
}
----------------------浅克隆-----------------------------
学生1: 123 - 引用的哈希编码1836019240
学生2: 123 - 引用的哈希编码325040804
学生1: 123 - 引用的哈希编码1836019240
学生2: 1189 - 引用的哈希编码325040804
学生1: 123地址北京市 - 地址的哈希编码1173230247 - 引用的哈希编码值为856419764
学生2: 123地址北京市 - 地址的哈希编码1173230247 - 引用的哈希编码值为621009875
学生1: 123地址河南省 - 地址的哈希编码1173230247 - 引用的哈希编码值为856419764
学生2: 123地址河南省 - 地址的哈希编码1173230247 - 引用的哈希编码值为621009875

深克隆代码示例

Student_deep

package JavaBean.CloneDemo.DeepClone;

import JavaBean.CloneDemo.ShallowClone.Address;

/**
 * @param
 * @Author: Daixt
 * @Date: 2022-08-05 11:37
 * @return
 **/

public class Student_deep implements Cloneable {
    private int number;
    private Address_deep address;

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public Address_deep getAddress() {
        return address;
    }

    public void setAddress(Address_deep address) {
        this.address = address;
    }

    //重写Object类下面clone()方法
    public Object clone() {
        Student_deep stu = null;
        try {
            stu = (Student_deep) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        stu.address = (Address_deep)address.clone();
        return stu;
    }
}

Address_deep

package JavaBean.CloneDemo.DeepClone;

public class Address_deep implements Cloneable{
    private  String  add;

    public String getAdd() {
        return add;
    }

    public void setAdd(String add) {
        this.add = add;
    }
    public Object clone(){
        Address_deep addr = null;
        try {
            addr = (Address_deep)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return addr;
    }
}

主函数

package Main;

import JavaBean.CloneDemo.DeepClone.Address_deep;
import JavaBean.CloneDemo.DeepClone.Student_deep;


public class CloneMain {
    public static void main(String[] args)  {
        System.out.println("----------------------深克隆-----------------------------");
        //深克隆

        Address_deep ad1 = new Address_deep();
        Student_deep sd1 = new Student_deep();
        ad1.setAdd("深克隆测试");
        sd1.setNumber(0001);
        sd1.setAddress(ad1);
        Student_deep sd2 = (Student_deep) sd1.clone();
        System.out.println("学生1: "+sd1.getNumber()+"地址"+sd1.getAddress().getAdd()+" - 地址的哈希编码"+ad1.hashCode()+" - 引用的哈希编码值为"+sd1.hashCode());
        System.out.println("学生1: "+sd2.getNumber()+"地址"+sd2.getAddress().getAdd()+" - 地址的哈希编码"+ad1.hashCode()+" - 引用的哈希编码值为"+sd2.hashCode());
         ad1.setAdd("深克隆");
        System.out.println("学生1: "+sd1.getNumber()+"地址"+sd1.getAddress().getAdd()+" - 地址的哈希编码"+ad1.hashCode()+" - 引用的哈希编码值为"+sd1.hashCode());
        System.out.println("学生1: "+sd2.getNumber()+"地址"+sd2.getAddress().getAdd()+" - 地址的哈希编码"+ad1.hashCode()+" - 引用的哈希编码值为"+sd2.hashCode());

    }
}

学生1: 1地址深克隆测试 - 地址的哈希编码1265094477 - 引用的哈希编码值为2125039532
学生1: 1地址深克隆测试 - 地址的哈希编码1265094477 - 引用的哈希编码值为312714112
学生1: 1地址深克隆 - 地址的哈希编码1265094477 - 引用的哈希编码值为2125039532
学生1: 1地址深克隆测试 - 地址的哈希编码1265094477 - 引用的哈希编码值为312714112

借鉴:点击跳转

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值