Java 深克隆和浅克隆
一、为什么要克隆?
使用场景: 当使用一个对象的属性时,需要进行一些修改,但是又不能直接修改该对象,此时我们就可以使用克隆来拷贝一个对象,进行操作。不然就需要new一个对象,对属性赋值。
总的来说为了保证引用类型的参数不被其他方法修改,可以使用克隆后的值作为参数传递。
一般情况下,我们实际需要使用的是深克隆。
二、如何克隆
- 浅克隆
对象的类实现Cloneable接口
重写Object类的clone()方法 - 深克隆
对象的类实现Cloneable接口
重写Object类的clone()方法
在clone()方法中手动赋值
三、代码**
浅克隆
public class Teacher implements Cloneable{
private Student student;
private int age;
public Teacher(Student student, int age) {
this.student = student;
this.age = age;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
protected Teacher clone() throws CloneNotSupportedException {
Teacher teacher = (Teacher)super.clone();
return teacher;
}
public class Student{
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Student student=new Student(1,"张三");
Teacher teacher=new Teacher(student,2);
Teacher clone = teacher.clone();
System.out.println(teacher.getStudent()==clone.getStudent());
clone.getStudent().setAge(3);
System.out.println(JSONObject.toJSON(clone));
System.out.println(JSONObject.toJSON(teacher));
}
}
运行结果
true
{"student":{"name":"张三","age":3},"age":2}
{"student":{"name":"张三","age":3},"age":2}
看结果可知:
1、teacher.clone() 生成对象,结果为true,说明两个student对象指向同一个内存地址
2、通过修改其中一个对象的属性值,结果两个对象的属性值都发生变化,说明两个student对象指向同一个内存地址
深克隆
public class Teacher implements Cloneable{
private Student student;
private int age;
public Teacher(Student student, int age) {
this.student = student;
this.age = age;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
protected Teacher clone() throws CloneNotSupportedException {
Teacher teacher = (Teacher)super.clone();
teacher.setStudent(this.getStudent().clone());
return teacher;
}
public class Student implements Cloneable{
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Student clone() throws CloneNotSupportedException {
return (Student)super.clone();
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Student student=new Student(1,"张三");
Teacher teacher=new Teacher(student,2);
Teacher clone = teacher.clone();
System.out.println(teacher.getStudent()==clone.getStudent());
clone.getStudent().setAge(3);
System.out.println(JSONObject.toJSON(clone));
System.out.println(JSONObject.toJSON(teacher));
}
结果
false
{"student":{"name":"张三","age":3},"age":2}
{"student":{"name":"张三","age":1},"age":2}
看结果可知:
1、teacher.clone() 生成对象,结果为false,说明两个student对象指向不同的内存地址
2、通过修改其中一个对象的属性值,结果其中一个对象的属性值发生变化,说明两个student对象指向不同的内存地址
回顾一下浅克隆和深克隆的概念
浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象里面包含的引用对象。
深克隆不仅拷贝对象本身,而且拷贝对象里面包含引用指向的所有对象。
END
谢谢!如有错误请指出,谢谢给位大佬