美文网首页
Java对象拷贝

Java对象拷贝

作者: Charein | 来源:发表于2019-02-20 20:19 被阅读0次

    常用的对象拷贝有2种方式,分别是浅拷贝深拷贝

    1. 浅拷贝

    在浅拷贝中,如果原型对象的成员变量是值类型,将复制一份给拷贝对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给拷贝对象,也就是说原型对象和拷贝对象的成员变量指向相同的内存地址。

    看如下例子

    public class ClassRoom implements Cloneable {
        public String name;
        public int studentNum;
        public Student student;
    
        public ClassRoom(String name, int studentNum, Student student) {
            this.name = name;
            this.studentNum = studentNum;
            this.student = student;
        }
    
        @Override
        public String toString() {
            return "ClassRoom{" +
                    "name='" + name + '\'' +
                    ", studentNum=" + studentNum +
                    ", student=" + student +
                    '}';
        }
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    
    public class Student implements Cloneable {
        public String name;
        public int age;
        public boolean isBoy;
    
        public Student(String name, int age, boolean isBoy) {
            this.name = name;
            this.age = age;
            this.isBoy = isBoy;
        }
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", isBoy=" + isBoy +
                    '}';
        }
    }
    

    拷贝Student对象测试

        public static void main(String[] args) {
            Student student = new Student("cyy", 20, true);
            System.out.println("student: " + student);
    
            Student studentNew;
            try {
                studentNew = (Student) student.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
                return;
            }
            student.name = "yt";
            student.age = 10;
            student.isBoy = false;
    
            System.out.println("studentNew: " + studentNew);
    
            // 输出
            // student: Student{name='cyy', age=20, isBoy=true}
            // studentNew: Student{name='cyy', age=20, isBoy=true}
        }
    

    从打印结果可以发现student对象里面的name,age,isBoy全部被拷贝到studentNew对象。

    如果对象里面又嵌套一个对象的情况

        public static void main(String[] args) {
            Student student = new Student("cyy", 20, true);
            ClassRoom classRoom = new ClassRoom("一年级", 100, student);
            System.out.println("classRoom: " + classRoom);
    
            ClassRoom classRoomNew;
            try {
                classRoomNew = (ClassRoom) classRoom.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
                return;
            }
    
            classRoom.name = "二年级";
            classRoom.studentNum = 200;
            classRoom.student.age = 10;
            classRoom.student.name = "yt";
            classRoom.student.isBoy = false;
    
            System.out.println("classRoomNew: " + classRoomNew);
    
            // 输出
            // classRoom: ClassRoom{name='一年级', studentNum=100, student=Student{name='cyy', age=20, isBoy=true}}
            // classRoomNew: ClassRoom{name='一年级', studentNum=100, student=Student{name='yt', age=10, isBoy=false}}
        }
    

    从打印结果可以发现classroom的name,studentNum内容被拷贝classroomNew对象,而student对象没有被拷贝过来(这时就需要使用深拷贝)。

    2.深拷贝

    在深拷贝中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给拷贝对象,深拷贝将原型对象的所有引用对象也复制一份给拷贝对象。

    看如下例子

    public class ClassRoom implements Cloneable {
        public String name;
        public int studentNum;
        public Student student;
    
        public ClassRoom(String name, int studentNum, Student student) {
            this.name = name;
            this.studentNum = studentNum;
            this.student = student;
        }
    
        @Override
        public String toString() {
            return "ClassRoom{" +
                    "name='" + name + '\'' +
                    ", studentNum=" + studentNum +
                    ", student=" + student +
                    '}';
        }
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            ClassRoom classRoom = (ClassRoom) super.clone();
            classRoom.student = (Student) student.clone();
            return classRoom;
        }
    }
    
    public class Student implements Cloneable {
        public String name;
        public int age;
        public boolean isBoy;
    
        public Student(String name, int age, boolean isBoy) {
            this.name = name;
            this.age = age;
            this.isBoy = isBoy;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", isBoy=" + isBoy +
                    '}';
        }
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    
      public static void main(String[] args) {
            Student student = new Student("cyy", 20, true);
            ClassRoom classRoom = new ClassRoom("一年级", 100, student);
            System.out.println("classRoom: " + classRoom);
    
            ClassRoom classRoomNew;
            try {
                classRoomNew = (ClassRoom) classRoom.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
                return;
            }
    
            classRoom.name = "二年级";
            classRoom.studentNum = 200;
            classRoom.student.age = 10;
            classRoom.student.name = "yt";
            classRoom.student.isBoy = false;
    
            System.out.println("classRoomNew: " + classRoomNew);
    
            // 输出
            // classRoom: ClassRoom{name='一年级', studentNum=100, student=Student{name='cyy', age=20, isBoy=true}}
            // classRoomNew: ClassRoom{name='一年级', studentNum=100, student=Student{name='cyy', age=20, isBoy=true}}
        }
    

    从打印结果可以发现classRoom对象的name,studentNum和student对象内容全部被拷贝到classRoomNew对象。

    注:浅拷贝/深拷贝需要实现Cloneable接口,并覆盖clone方法,而且clone方法必须是public访问。

    参考 https://blog.csdn.net/ztchun/article/details/79110096

    相关文章

      网友评论

          本文标题:Java对象拷贝

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