clone java的深克隆跟浅克隆
clone java的深克隆和浅克隆
浅复制(深克隆):将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
深复制(浅克隆):将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完
如有以下两个类
import java.io.Serializable; public class Teacher implements Cloneable,Serializable { private static final long serialVersionUID = 1L; private String name; private Integer age; private String sex; 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Student implements Cloneable,Serializable { private static final long serialVersionUID = 1L; private String name; private int age; private String sex; private Teacher teacher; 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } // clone public Student clone(){ Student student = null; try { student = (Student) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return student; } //deepClone(); public Student deepClone() throws Exception{ //将对象写入流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(this); //将对象从流中读出 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); Student student = (Student) ois.readObject(); ois.close(); bais.close(); oos.close(); baos.close(); return student; } }
新建测试类
public class TestCloneApp { public static void main(String[] args) throws Exception { Teacher teacher = new Teacher(); teacher.setName("张老师"); teacher.setAge(53); teacher.setSex("男"); Student student = new Student(); student.setAge(5); student.setName("张三"); student.setSex("女"); student.setTeacher(teacher); //clone Student cloneStudent = student.clone(); cloneStudent.setName("李四"); cloneStudent.setSex("男"); cloneStudent.getTeacher().setName("李老师");; //deepClone Student deepClone = student.deepClone(); deepClone.setName("aaa"); deepClone.setSex("bbb"); deepClone.getTeacher().setName("cccc"); System.out.println("person"+"------->"+"name: "+student.getName()+",age: "+student.getAge()+",sex: "+student.getSex()+",teacher: "+student.getTeacher().getName()); System.out.println("clonePerson"+"------->"+"name: "+cloneStudent.getName()+",age: "+cloneStudent.getAge()+",sex: "+cloneStudent.getSex()+",teacher: "+cloneStudent.getTeacher().getName()); System.out.println("deepClone"+" ------->"+"name: "+deepClone.getName()+",age: "+deepClone.getAge()+",sex: "+deepClone.getSex()+",teacher: "+deepClone.getTeacher().getName()); } }
输出结果如下
student------->name: 张三,age: 5,sex: 女,teacher: 李老师
cloneStudent------->name: 李四,age: 5,sex: 男,teacher: 李老师
deepClone ------->name: aaa,age: 5,sex: bbb,teacher: cccc
总结:
浅克隆会复制一个对象,对象属性是基本类型的会重现创建,相当于复制。而是引用类型的则是指向原对象的引用地址。所以当 cloneStudent 对象改变teacher姓名时,student对象的teacher姓名也改变。
深克隆也会复制一个对象,但是不管对象的属性是基本类型还是引用类型,都会重新辅助一份。所以当deepClone 改变任意属性时,原对象(student)的属性都不会受到影响。