Java中浅拷贝和深拷贝
原创
©著作权归作者所有:来自51CTO博客作者BusyCoder的原创作品,请联系作者获取转载授权,否则将追究法律责任
引入
浅拷贝
浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。
实现Cloneable重写clone
注:此方法默认是浅克隆
定义两个类Teacher和Student
Teacher类:
class Teacher implements Cloneable {
String name;
public Teacher(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
Student类:
class Student implements Cloneable {
String name;
Integer id;
Teacher teacher;
public Student(String name, Integer id, Teacher teacher) {
this.name = name;
this.id = id;
this.teacher = teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
", teacher=" + teacher +
'}';
}
}
测试:
public class CopyTest {
public static void main(String[] args) throws Exception {
Teacher teacher = new Teacher("李四老师");
Student student = new Student("张三", 12, teacher);
Student cloneStudent = (Student) student.clone();
System.out.println(student);
System.out.println(cloneStudent);
teacher.name = "王五老师";
System.out.println("=========修改老师信息后=========");
System.out.println(student);
System.out.println(cloneStudent);
}
}
}
输出结果:
Student{name='张三', id=12, teacher=Teacher{name='李四老师'}}
Student{name='张三', id=12, teacher=Teacher{name='李四老师'}}
=========修改老师信息后=========
Student{name='张三', id=12, teacher=Teacher{name='王五老师'}}
Student{name='张三', id=12, teacher=Teacher{name='王五老师'}}
图解:
分析:
两个student和cloneStudent指向不同的对象,但是两个引用student和copyStudent中的teacher引用指向的是同一个对象,所以说是浅拷贝。
深拷贝
深拷贝是把要复制的对象所引用的对象都复制一遍。
Teacher类:
class Teacher implements Cloneable {
String name;
public Teacher(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Student类:
class Student implements Cloneable {
String name;
Integer id;
Teacher teacher;
public Student(String name, Integer id, Teacher teacher) {
this.name = name;
this.id = id;
this.teacher = teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 浅复制时
// return super.clone();
//深复制时
Student student = (Student) super.clone();
student.teacher = (Teacher) student.teacher.clone();
return student;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
", teacher=" + teacher +
'}';
}
}
测试代码:
Teacher teacher1 = new Teacher("李四老师");
Student student = new Student("张三", 12, teacher1);
Student cloneStudent = (Student) student.clone();
System.out.println(student);
System.out.println(cloneStudent);
teacher.name = "王五老师";
System.out.println("=========修改老师信息后=========");
System.out.println(student);
System.out.println(cloneStudent);
结果:
Student{name='张三', id=12, teacher=Teacher{name='李四老师'}}
Student{name='张三', id=12, teacher=Teacher{name='李四老师'}}
=========修改老师信息后=========
Student{name='张三', id=12, teacher=Teacher{name='王五老师'}}
Student{name='张三', id=12, teacher=Teacher{name='李四老师'}}
结果分析:
两个引用student和copyStudent 指向不同的对象,这两个对象中的成员变量teacher是指向的两个对象,对teacher1修改只能影响到student对象,所以说是深拷贝。
图解(teacher姓名更改前)
图解(teacher姓名更改后)