美文网首页
Java——深拷贝/浅拷贝

Java——深拷贝/浅拷贝

作者: 四喜汤圆 | 来源:发表于2019-08-22 15:21 被阅读0次

    一、作用

    想拷贝一个新对象出来,并且对新对象的修改不会影响到旧对象。

    二、概念

    1. 浅拷贝

    对基本数据类型进行值传递,对引用数据类型进行引用传递,并没有创建新对象。

    2. 深拷贝

    对基本数据类型进行值传递,对引用数据类型进行引用传递,创建新对象,并复制其内容。

    三、使用

    1. 普通的

    JavaBean 中不包含引用类型数据(String 类型的成员可以有)

    public class Student implements Cloneable {
        private int id;
        private int age;
        private String name;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Student() {}
    
        public Student(int id, int age) {
            this.id = id;
            this.age = age;
        }
    
        public Student(int id, int age, String name) {
            this.id = id;
            this.age = age;
            this.name = name;
        }
    
        @NonNull
        @Override
        public Object clone() {
            Student o = null;
            try {
                o = (Student) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return o;
        }
    }
    
    @Test
    public void clone2() {
        Student s = new Student(1, 10, "小明");
        Student s2 = (Student) s.clone();
        System.out.println("s.hashcode=" + s.hashCode());
        System.out.println("s2.hashcode=" + s2.hashCode());
        s2.setAge(11);
        s2.setName("小红");
        System.out.println("s.age=" + s.getAge());
        System.out.println("s2.age=" + s2.getAge());
        System.out.println("s.name=" + s.getName());
        System.out.println("s2.name=" + s2.getName());
    }
    
    s.hashcode=458209687
    s2.hashcode=233530418
    s.age=10
    s2.age=11
    s.name=小明
    s2.name=小红
    

    2. 类中包含引用类型成员变量

    给 Student 中增加一引用类型成员

    private Farther mFarther;
    

    要想引用类型的实例成员也完成深拷贝,需要完成以下操作:

    • Farther 类实现Cloneable接口,重写clone()方法
    public class Farther implements Cloneable {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Farther() {}
    
        public Farther(String name) {
            this.name = name;
        }
    
        @NonNull
        @Override
        public Object clone() {
            Farther o = null;
            try {
                o = (Farther) super.clone();
                return o;
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return o;
        }
    }
    
    • 修改 Student 类的clone()方法
    @NonNull
    @Override
    public Object clone() {
        Student o = null;
        try {
            o = (Student) super.clone();
            o.setFarther((Farther) mFarther.clone());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return o;
    }
    

    测试

    @Test
    public void clone3() {
        Farther f1 = new Farther("小明爸爸");
        Student s = new Student(1, 10, "小明", f1);
        Student s2 = (Student) s.clone();
        System.out.println("s.hashcode=" + s.hashCode());
        System.out.println("s2.hashcode=" + s2.hashCode());
        s2.setAge(11);
        s2.setName("小红");
        System.out.println("s.age=" + s.getAge());
        System.out.println("s2.age=" + s2.getAge());
        System.out.println("s.name=" + s.getName());
        System.out.println("s2.name=" + s2.getName());
        System.out.println("s.farther.hashCode=" + s.getFarther().hashCode());
        System.out.println("s2.farther.hashCode=" + s2.getFarther().hashCode());
    }
    
    s.hashcode=458209687
    s2.hashcode=233530418
    s.farther.hashCode=683287027
    s2.farther.hashCode=1766822961
    

    3. List 的深拷贝

    List 的深拷贝,就是对其中的每个对象都完成深拷贝。

    @Test
    public void clone4() {
        List < Student > students = new ArrayList < > ();
    
        Farther f1 = new Farther("小明爸爸");
        Student s = new Student(1, 10, "小明", f1);
        students.add(s);
    
        Farther f2 = new Farther("小红爸爸");
        Student s2 = new Student(1, 10, "小红", f2);
        students.add(s2);
    
        List < Student > cloneStudents = new ArrayList < > ();
        for (int i = 0; i < students.size(); i++) {
            Student student = students.get(i);
            Student cloneStudent = (Student) student.clone();
            cloneStudents.add(cloneStudent);
        }
    
        for (int i = 0; i < students.size(); i++) {
            System.out.println("old:" + i + ":" + students.get(i).toString());
            System.out.println("new:" + i + ":" + cloneStudents.get(i).toString());
        }
    }
    

    测试结果

    old:0:Student{student.hashCode=458209687, name='小明', mFarther,hashCode=233530418}
    new:0:Student{student.hashCode=683287027, name='小明', mFarther,hashCode=1766822961}
    old:1:Student{student.hashCode=254413710, name='小红', mFarther,hashCode=1496724653}
    new:1:Student{student.hashCode=553264065, name='小红', mFarther,hashCode=897697267}
    

    参考文献

    深拷贝和浅拷贝

    相关文章

      网友评论

          本文标题:Java——深拷贝/浅拷贝

          本文链接:https://www.haomeiwen.com/subject/ltwgsctx.html