java-深克隆和浅克隆
文章参考 https://www.cnblogs.com/acode/p/6306887.html
一、前提
1、使用clone()方法的类,必须实现Cloneable接口,
否则调用clone()方法时候,会抛出 CloneNotSupportedException
2、clone()为protected修饰符方法,所以如果想使用clone()方法,必须在子类中实现
二、实战
类关系(
Student:两个基础类型属性
一个引用类型属性)
1、创建一个Student类
@Data
public class Student implements Cloneable{
private String name;
private int age;
private Mother mother ;
@Override
protected Object clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();
try {
Mother mother1 = (Mother)mother.clone();
student.setMother(mother1);
} catch (Exception e) {
e.printStackTrace();
}
return student;
}
}
2、创建一个Mother类
@Data public class Mother implements Cloneable { private String name; private int age; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
3、创建一个测试类
public class Test {
public static void main(String[] args) throws Exception {
//============初始化================
Mother mother = new Mother();
mother.setName("小王mama");
mother.setAge(40);
Student student = new Student();
student.setAge(1);
student.setName("小王");
student.setMother(mother);
//============克隆================
Student student2 = (Student)student.clone();
student2.setName("小李");
student2.setAge(2);
student2.getMother().setAge(45);
student2.getMother().setName("小李mama");
//============输出================
System.out.println(student);
System.out.println(student2);
}
}
三、结果
Student(name=小王, age=1, mother=Mother(name=小王mama, age=40))
Student(name=小李, age=2, mother=Mother(name=小李mama, age=45))
四、分析
1、结果实现类深度克隆
2、如果在Student类的clone()方法中没有,进行Mother类的操作,则Mother属性只会进行引用操作
修改Student类中的clone()方法
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
结果
Student(name=小王, age=1, mother=Mother(name=小李mama, age=45))
Student(name=小李, age=2, mother=Mother(name=小李mama, age=45))
3、歪门邪术(实现序列化接口,实现clone) 对象串行化,但是串行化却很耗时,在一些框架中,我们便可以感受到,它们往往将对象进行串行化后进行传递,耗时较多。
@Data public class Student implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; private Mother mother ; public Object deepClone() throws IOException, ClassNotFoundException { // 将对象写到流里 ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); // 从流里读出来 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); return (oi.readObject()); } }
@Data public class Mother implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; }
结果:深度克隆成功
Student(name=小王, age=1, mother=Mother(name=小王mama, age=40))
Student(name=小李, age=2, mother=Mother(name=小李mama, age=45))