java 深clone与浅clone
上图来自https://baijiahao.baidu.com/s?id=1639373055719110771&wfr=spider&for=pc
上图来自https://blog.csdn.net/houwanle/article/details/82218174
- 浅复制只是复制引用的地址
- 深复制把都对象复制两份
java中原生的 clone 是浅复制,他只是把对象的引用复制一次,对对象的修改,所有引用的对象都会发生改变
-
实践
-
teacher 类
import java.io.Serializable;
/**
* @description:
* @author: Seldom
* @time: 2020/4/27 22:23
*/
public class Teacher implements Serializable {
private String name;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Teacher(String name, int age) {
this.name = name;
this.age = 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;
}
}
ClassRoom1类(浅复制)
/**
* @description: 浅clone
* @author: Seldom
* @time: 2020/4/27 22:24
*/
public class ClassRoom1 implements Cloneable{
private Teacher teacher;
private int studentCount;
@Override
public String toString() {
return "ClassRoom{" +
"teacher=" + teacher +
", studentCount=" + studentCount +
'}';
}
public ClassRoom1(Teacher teacher, int studentCount) {
this.teacher = teacher;
this.studentCount = studentCount;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public int getStudentCount() {
return studentCount;
}
public void setStudentCount(int studentCount) {
this.studentCount = studentCount;
}
/**
*
* @return 浅clone
* @throws CloneNotSupportedException
*/
@Override
protected ClassRoom1 clone() throws CloneNotSupportedException {
return (ClassRoom1) super.clone();
}
}
ClassRoom2 深复制
import java.util.List;
/**
* @description: 深clone
* @author: Seldom
* @time: 2020/4/27 22:24
*/
public class ClassRoom2 implements Cloneable{
private Teacher teacher;
private int studentCount;
@Override
public String toString() {
return "ClassRoom{" +
"teacher=" + teacher +
", studentCount=" + studentCount +
'}';
}
public ClassRoom2(Teacher teacher, int studentCount) {
this.teacher = teacher;
this.studentCount = studentCount;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public int getStudentCount() {
return studentCount;
}
public void setStudentCount(int studentCount) {
this.studentCount = studentCount;
}
/**
*
* @return 深clone
*/
@Override
protected ClassRoom2 clone() {
return new ClassRoom2(this.teacher, this.studentCount);
}
}
- 通过序列化深复制
import java.io.Serializable;
import java.util.List;
/**
* @description: 深clone,通过序列化
* @author: Seldom
* @time: 2020/4/27 22:24
*/
public class ClassRoom3 implements Serializable {
private Teacher teacher;
private int studentCount;
@Override
public String toString() {
return "ClassRoom{" +
"teacher=" + teacher +
", studentCount=" + studentCount +
'}';
}
public ClassRoom3(Teacher teacher, int studentCount) {
this.teacher = teacher;
this.studentCount = studentCount;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public int getStudentCount() {
return studentCount;
}
public void setStudentCount(int studentCount) {
this.studentCount = studentCount;
}
/**
*
* @return 深clone
*/
@Override
protected ClassRoom2 clone() {
return new ClassRoom2(this.teacher, this.studentCount);
}
}
测试代码
package clone;
import java.io.*;
/**
* @description: 深clone 浅clone
* @author: Seldom
* @time: 2020/4/27 22:21
*/
public class MainClone {
public static void main(String[] args) throws Exception {
// 浅 clone
ClassRoom1 classRoom1 = new ClassRoom1(new Teacher("seldom", 20), 18);
ClassRoom1 classRoom1Clone = classRoom1.clone();
System.out.printf("clone:%s\n", classRoom1Clone);
classRoom1.getTeacher().setName("joke");
System.out.printf("after:%s\n", classRoom1Clone);
// 深 clone
ClassRoom2 classRoom2 = new ClassRoom2(new Teacher("seldom", 20), 18);
ClassRoom2 classRoom2Clone = classRoom2.clone();
System.out.printf("clone:%s\n", classRoom2Clone);
classRoom1.getTeacher().setName("joke");
System.out.printf("after:%s\n", classRoom2Clone);
// 深 clone 通过序列化
ClassRoom3 classRoom3 = new ClassRoom3(new Teacher("seldom", 20), 18);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(classRoom3);
// 从流中读出对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
ClassRoom3 classRoom3Clone = (ClassRoom3) ois.readObject();
System.out.printf("clone:%s\n", classRoom3Clone);
classRoom3.getTeacher().setName("joke");
System.out.printf("after:%s\n", classRoom3Clone);
}
}
======================输出=================================
clone:ClassRoom{teacher=Student{name='seldom', age=20}, studentCount=18}
after:ClassRoom{teacher=Student{name='joke', age=20}, studentCount=18} // 对于浅复制,改变了对象内容
clone:ClassRoom{teacher=Student{name='seldom', age=20}, studentCount=18}
after:ClassRoom{teacher=Student{name='seldom', age=20}, studentCount=18}
clone:ClassRoom{teacher=Student{name='seldom', age=20}, studentCount=18}
after:ClassRoom{teacher=Student{name='seldom', age=20}, studentCount=18}