浅复制(浅克隆):将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
深复制(深克隆):将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完
如有以下两个类
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)的属性都不会受到影响。