克隆分来浅克隆、深度克隆。要想实现克隆必须要
浅克隆:A = B.clone(), A == B 为true,即指向内存地址相同
深克隆:A = B.clone(), A == B 为false,即内存地址不同,是两个独立的对象
如何实现深克隆,例如:A类中有成员变量为B类,A类与B类要同时实现cloneable接口和重写clone方法并在A的clone()中调用B类的克隆方法给成员变量赋值才能实现深克隆
//深克隆示例:
public class Student implements Cloneable{
private int age;
private String name;
private Integer code;
@Override
protected Teacher clone() throws CloneNotSupportedException {
Teacher tea = (Teacher)super.clone();
tea.student = (Student) tea.student.clone();
return tea;
}
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
Student student = new Student();
student.setAge(18);
student.setCode(18);
student.setName("AStundent");
teacher.setAge(10);
teacher.setCode(1);
teacher.setName("ATeacher");
teacher.setStudent(student);
Teacher clone = teacher.clone();
//false,表示空间地址不同了
System.out.println(clone.student == teacher.student);
//false,表示空间地址不同了
System.out.println(clone == teacher);
/**
深度克隆后发现,两对象String所指向的地址相同,不仅仅是String,
其他几个成员变量地址也相同,为什么深度拷贝后这些成员变量的地址还相同?
这是因为有常量池的存在例如:String a = "1"与String b = "1"的地址就是相同的
a == b,都指向了java内存中的常量池中,当你修改a = "2"时,a会指向"2"所在常量池中的地址
而不是将a所指向内存地址中的值改为"2",因此修改后 a != b
**/
//true
System.out.println(clone.getName() == teacher.getName());
/**
更改过后变为false,地址不同了
**/
clone.setName("change");
//false
System.out.println(clone.getName() == teacher.getName());
}
}
public class Teacher implements Cloneable{
private int age;
private String name;
private Integer code;
private Student student;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}