深浅克隆
开过过程中,有时一些对象在逻辑操作中可能值被修改,但是后续操作可能还需要用到没有改变之前的对象,对于这种情况可以使用clone方法来克隆一个相同的对象以便支持后续使用;
⑴浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
⑵深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
package com.osc.demo; import java.util.List; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; public class Teacher implements Cloneable { private String name; private int age; private List<Student> student; 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 List<Student> getStudent() { return student; } public void setStudent(List<Student> student) { this.student = student; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }
package com.osc.demo; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; public class Student { 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 ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }
package com.osc.demo; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { Student student = new Student(); student.setName("张柏芝"); student.setAge(34); List<Student> list = new ArrayList<Student>(); list.add(student); Teacher teacher = new Teacher(); teacher.setName("陈冠希"); teacher.setAge(33); teacher.setStudent(list); try { Teacher cloneTeacher = (Teacher) teacher.clone(); System.out.println("修改前teacher:" + teacher); System.out.println("修改前cloneTeacher:" + cloneTeacher); System.out.println("--modify--"); student.setName("钟欣桐"); student.setAge(33); System.out.println("修改后teacher:" + teacher); System.out.println("修改后cloneTeacher:" + cloneTeacher); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
--
修改前teacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]
修改前cloneTeacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]
--modify--
修改后teacher:Teacher[name=陈冠希,age=33,student=[Student[name=钟欣桐,age=33]]]
修改后cloneTeacher:Teacher[name=陈冠希,age=33,student=[Student[name=钟欣桐,age=33]]]
-------
使用SerializationUtils.clone(obj)重写clone()实现深克隆,利用Serializable进行深拷贝的时候成员属性也必须是Serializable的,否则只返回一个引用
深克隆:
package com.osc.demo; import java.io.Serializable; import java.util.List; import org.apache.commons.lang.SerializationUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; @SuppressWarnings("serial") public class Teacher implements Cloneable, Serializable { private String name; private int age; private List<Student> student; 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 List<Student> getStudent() { return student; } public void setStudent(List<Student> student) { this.student = student; } @Override protected Object clone() throws CloneNotSupportedException { return SerializationUtils.clone(this); } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }
package com.osc.demo; import java.io.Serializable; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; @SuppressWarnings("serial") public class Student implements Serializable { 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 ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }
package com.osc.demo; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { Student student = new Student(); student.setName("张柏芝"); student.setAge(34); List<Student> list = new ArrayList<Student>(); list.add(student); Teacher teacher = new Teacher(); teacher.setName("陈冠希"); teacher.setAge(33); teacher.setStudent(list); try { Teacher cloneTeacher = (Teacher) teacher.clone(); System.out.println("修改前teacher:" + teacher); System.out.println("修改前cloneTeacher:" + cloneTeacher); System.out.println("--modify--"); student.setName("钟欣桐"); student.setAge(33); System.out.println("修改后teacher:" + teacher); System.out.println("修改后cloneTeacher:" + cloneTeacher); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
--
修改前teacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]
修改前cloneTeacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]
--modify--
修改后teacher:Teacher[name=陈冠希,age=33,student=[Student[name=钟欣桐,age=33]]]
修改后cloneTeacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]