资讯专栏INFORMATION COLUMN

java基础——浅克隆与深克隆

winterdawn / 827人阅读

摘要:为什么使用存在一个对象,已有初始值,这时候可能需要一个新的对象和相同,但是和是两个独立的对象,任意一个改动都不影响其中一个的值,但是的初始值由确定,这时候就是最有效也是最简单的方法。

为什么使用clone

存在一个对象A,A已有初始值,这时候可能需要一个新的对象B和A相同,但是A和B是两个独立的对象,任意一个改动都不影响其中一个的值,但是B的初始值由A确定,这时候clone就是最有效也是最简单的方法。

new一个对象和clone一个对象的区别

new操作符的本意是分配内存空间,java程序执行到new操作符时,首先去看new操作符后面的类型,知道类型才能知道需要分配多大的内存空间,分配完成,调用构造函数,填充对象,完成对象的初始化。

clone的第一步也是分配内存,java程序执行到clone这一步时,分配的内存和调用clone方法的对象相同,在根据原对象完成对新对象的初始化,一个新的对象就被创建完成。

复制对象和克隆对象

需要克隆的对象要继承Cloneable接口,并重写clone()方法

复制对象

定义类:

public class People1 {
    private String name;
    private Integer age;

    public People1(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

复制测试

public class test {
    public static void main(String[] args) {
        People1 people1 = new People1("people",18);
        People1 people11 = people1;

        System.out.println(people1);
        System.out.println(people11);
        System.out.println(people1 == people11);
    }
}

结果:

证明复制对象只是指向原来的对象,people1和people11只是引用同一个对象

clone对象

定义类:

public class People2 implements Cloneable{
    private String name;
    private Integer age;

    public People2(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }
    
    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

测试:

public class test {
    public static void main(String[] args) {
        
        //clone
        People2 people2 = new People2("people",18);
        People2 people22 = null;
        try {
            people22 = (People2) people2.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        System.out.println(people2);
        System.out.println(people22);
        System.out.println(people2 == people22);
    }
}

结果:


可以看出people2和people22指向的对象并不是同一个的

浅克隆与深克隆

定义类:
Student类:

public class Student implements Cloneable{
    private String name;
    private Integer age;
    private Teacher teacher;

    public Student(String name, Integer age,Teacher teacher) {
        this.name = name;
        this.age = age;
        this.teacher = teacher;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
     public String toString() {
         return "学生: name=" + name + ", age=" + age + ",指导" + teacher;
      }

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

Teacher类

public class Teacher {
    private String name;
    private Integer age;

    public Teacher(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "老师:name=" + name + ", age=" + age ;
    }
}
浅克隆

main函数

public class test2 {
    public static void main(String[] args) {
        Teacher teacher = new Teacher("刘老师",18);
        Student student1 = new Student("小明",10,teacher);
        Student student2 = null;
        try {
            student2 = (Student) student1.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        Teacher t1 = student2.getTeacher();
        t1.setName("张老师");
        t1.setAge(30);
        student2.setName("小红");
        student2.setAge(9);
        student2.setTeacher(t1);
        System.out.println(student1);
        System.out.println(student2);
    }
}

结果:

修改student2中的Teacher类,student1也跟着改变,而修改姓名和年龄并不会修改,由此得出才重新clone方法时不能直接super

深克隆

Teacher继承Cloneable

Student重写clone方法

        Student newStudent = (Student) super.clone();
        newStudent.teacher = (Teacher) teacher.clone();
        return newStudent;

运行上方测试代码,结果:


完成预想结果

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75469.html

相关文章

  • Java实现对象克隆的方法

    摘要:优点简单易实现缺点无法真正克隆对象深克隆实现通过递归克隆实现代码输出通过序列化实现代码输出结果分析采用深克隆能有效隔离源对象与克隆对象的联系。 本文首发于cartoon的博客     转载请注明出处:https://cartoonyu.github.io/cartoon-blog/post/java/java%E5%AE%9E%E7%8E%B0%E5%85%8B%E9%9A%86%E...

    zhoutk 评论0 收藏0
  • 拷贝与深拷贝

    摘要:二浅拷贝与深拷贝深拷贝和浅拷贝是只针对和这样的引用数据类型的。浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。对于字符串数字及布尔值来说不是或者对象,会拷贝这些值到新的数组里。 一、数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型。 基本数据类型的特点:直...

    hzc 评论0 收藏0
  • 拷贝与深拷贝

    摘要:二浅拷贝与深拷贝深拷贝和浅拷贝是只针对和这样的引用数据类型的。浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。对于字符串数字及布尔值来说不是或者对象,会拷贝这些值到新的数组里。 一、数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型。 基本数据类型的特点:直...

    史占广 评论0 收藏0
  • 拷贝与深拷贝的区别

    摘要:浅拷贝与深拷贝一数据类型数据分为基本数据类型,和对象数据类型。浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。对于字符串数字及布尔值来说不是或者对象,会拷贝这些值到新的数组里。 浅拷贝与深拷贝 一、数据类型数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型。 基本数据类...

    jsyzchen 评论0 收藏0
  • 关于JavaScript的拷贝和深拷贝

    摘要:引用类型值引用类型值是保存在堆内存中的对象,变量保存的只是指向该内存的地址,在复制引用类型值的时候,其实只复制了指向该内存的地址。 前言 要理解 JavaScript中浅拷贝和深拷贝的区别,首先要明白JavaScript的数据类型。JavaScript有两种数据类型,基础数据类型和引用数据类型。js的基本类型:undefined,null,string,boolean,number,s...

    shenhualong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<