持续学习合集--java克隆(浅克隆和深克隆)

前言

克隆,即复制一个对象。日常编程中,我们常常需要对一个对象进行复制然后操作,普通的做法就是new出一个对象,一个个赋值;如果对象属性偏多,编写的代码则很臃肿;
在java中,Object类中实现了clone方法,用于克隆对象。

java的克隆

在java中克隆主要为浅克隆和深克隆;
实现克隆的方式主要是以下几个步骤

  1. 对象类实现Cloneable接口
  2. 重写Object类中的clone方法(最好定义为public权限)
  3. 重写的clone方法中根据自己需要编写相应逻辑(浅克隆和深克隆)
何为深克隆和浅克隆

浅克隆:复制对象时仅仅复制对象本身,包括基本属性,但该对象的属性引用其他对象时,该引用对象不会被复制,即拷贝出来的对象与被拷贝出来的对象中的属性引用的对象是同一个。
深克隆:复制对象本身的同时,也复制对象包含的引用指向的对象,即修改被克隆对象的任何属性都不会影响到克隆出来的对象。

文字的表述有时很饶人,直接来代码体现吧;

public class Student implements  Cloneable{
    private int num;
    private String name;
    
    public Student() {
    }

    public Student(int num, String name) {
        this.num = num;
        this.name = name;
        
    }

    public int getNum() {
        return num;
    }


    public void setNum(int num) {
        this.num = num;
    }


    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "num=" + num +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

测试类:

public static void main(String[] args) throws CloneNotSupportedException {
   Student a = new Student(1,"tom");
   Student b = (Student) a.clone();
   b.setNum(2);
   b.setName("david");
   System.out.println(a.toString());
   System.out.println(b.toString());
}

测试结果:
在这里插入图片描述
由测试结果可以看出:
创建a学生,a学生克隆到b学生。
然后修改b学生的值,他们的值是互相不影响的。

接下来我们来看看,在对象内有属性不是基本类型的时候;

// 修改后的学生类,加入了新的属性Achievement对象
public class Student implements  Cloneable{
    private int num;
    private String name;
    private Achievement achievement;

    public Student() {
    }

    public Student(int num, String name, Achievement achievement) {
        this.num = num;
        this.name = name;
        this.achievement = achievement;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

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

    public Achievement getAchievement() {
        return achievement;
    }

    public void setAchievement(Achievement achievement) {
        this.achievement = achievement;
    }

    @Override
    public String toString() {
        return "Student{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", achievement=" + achievement +
                '}';
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// Achievement成绩类
public class Achievement implements  Cloneable{
    private float math;
    private float english;

    public Achievement() {
    }

    public Achievement(float math, float english) {
        this.math = math;
        this.english = english;
    }

    public float getMath() {
        return math;
    }

    public void setMath(float math) {
        this.math = math;
    }

    public float getEnglish() {
        return english;
    }

    public void setEnglish(float english) {
        this.english = english;
    }

    @Override
    public String toString() {
        return "Achievement{" +
                "math=" + math +
                ", english=" + english +
                '}';
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

测试类:

public class test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Achievement achievement = new Achievement(60,90);
        Student a = new Student(1,"tom",achievement);
        Student b = (Student) a.clone();
        b.setNum(2);
        b.setName("david");
        System.out.println(a.toString());
        System.out.println(b.toString());
        // 修改b学生属性achievement的值
        b.getAchievement().setMath(70);
        b.getAchievement().setEnglish(40);
        System.out.println("修改后~~~~");
        System.out.println(a.toString());
        System.out.println(b.toString());
    }
}

测试结果:
在这里插入图片描述
由结果我们可以很清晰的看出:
修改b学生achievement属性的值,两个对象的achievement属性的值都会改变,这就是浅克隆;

如何实现深克隆?

继续我们直接上代码:

public class Student implements  Cloneable{
    private int num;
    private String name;
    private Achievement achievement;

   	// get set .......
    
    // 主要是修改克隆方法中逻辑
    // 对象仍然正常赋值,然而属性achievement使用当前对象的Achievement对象的clone方法进行克隆;
    @Override
    public Object clone() throws CloneNotSupportedException {
        Student student = (Student) super.clone();
        student.achievement = (Achievement) this.getAchievement().clone();
        return student;
    }
}

测试类:(和之前一样)

public class test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Achievement achievement = new Achievement(60,90);
        Student a = new Student(1,"tom",achievement);
        Student b = (Student) a.clone();
        b.setNum(2);
        b.setName("david");
        System.out.println(a.toString());
        System.out.println(b.toString());
        b.getAchievement().setMath(70);
        b.getAchievement().setEnglish(40);
        System.out.println("修改后~~~~");
        System.out.println(a.toString());
        System.out.println(b.toString());
    }
}

测试结果:
在这里插入图片描述
由测试结果我们可以看出,num为1的学生和num为2的学生的成绩都不一样了,这样我们就完成了深克隆的操作。

我们使用一组图来清晰的表示一下:

  • 浅克隆
    在这里插入图片描述
  • 深克隆
    在这里插入图片描述

这样就是一个简单的java克隆(浅克隆和深克隆)的理解。

参考资料:
深入理解Java的浅克隆与深克隆

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值