Java基础——克隆、浅拷贝、深拷贝、数组的浅拷贝方法Arrays.copyOf()

克隆

拷贝与克隆

  • 拷贝:此时,变量dogA和dogB指向着同一个对象,任何一个变量改变都会影响另一个变量

    • Dog dogA = new Dod();
      Dog dogB = dogA;
      
  • 克隆

    • 浅拷贝:默认的克隆操作是“浅拷贝”,浅拷贝并没有克隆对象中引用的其他对象

      package com.kelvin.clone_test;
      
      public class Student implements Cloneable{ // 需要实现标记接口Cloneable才可以用Clone方法
          String name;
          int age;
          Teacher teacher;
      
          /*省略了get set toString 和 构造方法*/
          
      	// 浅拷贝(为了使该类以外的类(ShallowCopyTest)也能对Student进行clone,需要将该方法变为public)
          // 原Object中的clone为protected
          public Student clone() throws CloneNotSupportedException {
              return (Student) super.clone();
          }
      
          // 深拷贝
          public Student hardClone () throws CloneNotSupportedException {
              Student cStudent = (Student) super.clone();
              cStudent.teacher = this.teacher.clone();
              return cStudent;
          }
      }
      
      package com.kelvin.clone_test;
      
      public class Teacher implements Cloneable{
          String name;
          int age;
      	
          /*省略了get set toString 和 构造方法*/
          
          // Student的深拷贝拷贝需要克隆Teacher所以需要将方法变为public
          public Teacher clone() throws CloneNotSupportedException {
              return (Teacher) super.clone();
          }
      }
      
      
      package com.kelvin.clone_test;
      
      // 浅拷贝
      public class ShallowCopyTest {
          public static void main(String[] args) throws CloneNotSupportedException {
              Teacher teacher = new Teacher("XinYuan", 22);
              Student kelvin = new Student("Kelvin.Su", 23, teacher);
              Student cKelvin = (Student) kelvin.clone();
      
              // 克隆后没有进行别的操作,这里的输出是一样的
              System.out.println(kelvin);
              System.out.println(cKelvin + "\n");
      
              // 做一些修改来验证浅拷贝的特性
              kelvin.setName("SuKaiWen");
              teacher.setName("LiuXinYuan");
      
              // 可以看到现在kelvin与cKelvin是两个不同的对象,对Kelvin修改name字段并不会影响到cKelvin
              // 但是kelvin与cKelvin的teacher字段指向着同一个对象,对teacher做修改,kelvin与cKelvin的teacher字段都会被修改
              System.out.println(kelvin);
              System.out.println(cKelvin);
              
              /* 输出:
              Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}}
              Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}}
      
              Student{name='SuKaiWen', age=23, teacher=Teacher{name='LiuXinYuan', age=22}}
              Student{name='Kelvin.Su', age=23, teacher=Teacher{name='LiuXinYuan', age=22}}
          	*/
          }
      }
      
    • 深拷贝

      package com.kelvin.clone_test;
      
      public class DeepCopyTest {
          public static void main(String[] args) throws CloneNotSupportedException {
              Teacher teacher = new Teacher("XinYuan", 22);
              Student kelvin = new Student("Kelvin.Su", 23, teacher);
              Student cKelvin = (Student) kelvin.hardClone();
      
              // 克隆后没有进行别的操作,这里的输出是一样的
              System.out.println(kelvin);
              System.out.println(cKelvin + "\n");
      
              // 做一些修改来验证浅拷贝的特性
              kelvin.setName("SuKaiWen");
              teacher.setName("LiuXinYuan");
      
              // 经过深拷贝的Student修改kelvin的teacher字段并不会改变cKelvin的teacher字段
              System.out.println(kelvin);
              System.out.println(cKelvin);
              
              /* 输出:
              Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}}
              Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}}
      
              Student{name='SuKaiWen', age=23, teacher=Teacher{name='LiuXinYuan', age=22}}
              Student{name='Kelvin.Su', age=23, teacher=Teacher{name='XinYuan', age=22}}
              */
          }
      }
      
      // 深拷贝
      public Student hardClone () throws CloneNotSupportedException {
          Student cStudent = (Student) super.clone();
          cStudent.teacher = this.teacher.clone();
          return cStudent;
      }
      
    • Array.copyOf()是浅拷贝

      public class CopyOfTest {
          public static void main(String[] args) {
              Teacher teacher = new Teacher("XinYuan", 22);
              Student kelvin = new Student("Kelvin.Su", 23, teacher);
              Student[] students = new Student[1];
              students[0] = kelvin;
              Student[] cStudents = Arrays.copyOf(students, students.length);
      
      
              // Arrays.copyOf后没有进行别的操作,这里的输出是一样的
              System.out.println(students[0]);
              System.out.println(cStudents[0]);
      
              // 做一些修改来验证浅拷贝的特性
              kelvin.setName("SuKaiWen");
              teacher.setName("LiuXinYuan");
      
              // 可以看到现在students[0]与cStudents[0]是两个不同的对象,对students[0]修改name字段并不会影响到cStudents[0]
              // 但是students[0]与cStudents[0]的teacher字段指向着同一个对象,对teacher做修改,students[0]与cStudents[0]的teacher字段都会被修改
              System.out.println(students[0]);
              System.out.println(cStudents[0]);
          }
      }
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值