clone中的浅复制和深复制
Posted warriors-curry
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了clone中的浅复制和深复制相关的知识,希望对你有一定的参考价值。
clone:用于两个对象有相同的内容时,进行复制操作。
提示:Java中要想自定义类的对象可以被复制,自定义类就必须实现Cloneable中的clone()方法。
浅复制:另一个对象用clone()方法对已经存在的对象进行复制的时候,会改变被复制对象里面所有的内容,换句话说,浅复制就是对对象的复制出现了一些问题。
深复制:另一个对象对已有的对象进行相同的内容复制的时候,不会改变原对象的内容
什么情况下会出现浅复制呢?用下面的例子进行说明:
学生类:
public class Student implements Cloneable { private String name; private int age; private Professor professor; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Professor getProfessor() { return professor; } public void setProfessor(Professor professor) { this.professor = professor; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", professor=" + professor + "]"; } public Object clone() throws CloneNotSupportedException{ return super.clone(); } }
教授类:
public class Professor { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Professor [name=" + name + ", age=" + age + "]"; } }
案例一:
public class ShadowCopy { public static void main(String[] args) { Professor p1 = new Professor(); p1.setName("Professor Zhang"); p1.setAge(30); Student s1 = new Student(); s1.setName("xiao ming"); s1.setAge(18); s1.setProfessor(p1); System.out.println(s1); try { Student s2 = (Student) s1.clone(); Professor p2 = s2.getProfessor(); p2.setName("Professor Li"); p2.setAge(45); s2.setProfessor(p2); System.out.println("复制后的:s1 = " + s1); System.out.println("复制后的:s2 = " + s2); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
运行结果1:
1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]] 2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]] 3 复制后的:s2 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]
s1的导师为30岁的Professor Zhang,恰巧s2与s1同名同岁,但是s2的导师为45岁的Professor Li,于是我们直接复制s1给s2,再修改下s2的导师的信息。可是,问题出现了,当我们修改了s2的导师后,s2的信息是正确的,但是s1的导师信息也跟着修改了。
案例二:
public class ShadowCopy { public static void main(String[] args) { Professor p1 = new Professor(); p1.setName("Professor Zhang"); p1.setAge(30); Student s1 = new Student(); s1.setName("xiao ming"); s1.setAge(18); s1.setProfessor(p1); System.out.println(s1); try { Student s2 = (Student) s1.clone(); s2.setName("xiao hong"); s2.setAge(17); Professor p2 = s2.getProfessor(); p2.setName("Professor Li"); p2.setAge(45); s2.setProfessor(p2); System.out.println("复制后的:s1 = " + s1); System.out.println("复制后的:s2 = " + s2); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
运行结果二:
1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]] 2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]] 3 复制后的:s2 = Student [name=xiao hong, age=17, professor=Professor [name=Professor Li, age=45]]
这次,我们在clone后,又修改了s2的name和age,从结果可以看出,s1的name和age并没有因为s2的修改而改变。
以上出现的两种情况,就是我们所说的浅复制,但我们实际上不希望出现这两种问题,如何解决呢?那我们必须就要进行深复制。接下来就是我要说的深复制
public class Professor implements Cloneable { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Professor [name=" + name + ", age=" + age + "]"; } public Object clone() throws CloneNotSupportedException{ return super.clone(); } }
public class Student implements Cloneable { private String name; private int age; private Professor professor; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Professor getProfessor() { return professor; } public void setProfessor(Professor professor) { this.professor = professor; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", professor=" + professor + "]"; } public Object clone() throws CloneNotSupportedException{ Student newStudent = (Student) super.clone(); newStudent.professor = (Professor) professor.clone(); return newStudent; } }
再次运行案例一:
1.Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]] 2.复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]] 3.复制后的:s2 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Li, age=45]]
再次运行案例二:
1 Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]] 2 复制后的:s1 = Student [name=xiao ming, age=18, professor=Professor [name=Professor Zhang, age=30]] 3 复制后的:s2 = Student [name=xiao hong, age=17, professor=Professor [name=Professor Li, age=45]]
以上就是我们所说的深复制。好好去领悟哦!
参考博客:https://www.cnblogs.com/acode/p/6306887.html
以上是关于clone中的浅复制和深复制的主要内容,如果未能解决你的问题,请参考以下文章