昨天偶然遇到有人问到关系深克隆和浅克隆的问题,于是我仿写了一个例子,但是我发现打印出来的效果不尽人意:
自定义的teacher,重写了clone方法
public class Teacher implements Cloneable {
private String name;
private String course;
public Teacher(String name, String course) {
this.name = name;
this.course = course;
}
public Teacher clone() {
Teacher clone = null;
try {
clone = (Teacher) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
@Override
public String toString() {
return this.getName() + " " + this.getCourse();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
}
自定义student,重写了
public class Student implements Cloneable {
private String name;
private int age;
private Teacher teacher;
public Student(String name, int age, Teacher teacher) {
this.name = name;
this.age = age;
this.teacher = teacher;
}
public Student clone() {
Student student = null;
try {
student = (Student) super.clone();
// Teacher teacher = this.teacher.clone();
//
// student.setTeacher(teacher);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return student;
}
@Override
public String toString() {
return this.getName() + " " + this.getAge() + " " + this.getTeacher();
}
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;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
测试如下:
产生疑问,浅克隆不是修改clone对象的teacher字段,原来的student也会改变吗?
至此,需要从clone方法说起,clone方法是一个native方法,它是C语言的一个动态链接库,他的作用是将student对象的内存克隆一份。如下图:
clone.setTeacher(new Teacher("新来的老师","日语"));
这一行代码发生如下变化:
所以修改clone对象的老师,student对象的老师不发生变化。
正确的操作:此时修改的是地址为0031003的老师的姓名,并没有更换新的老师,所以clone对象改变的时候,student对象也发生变化
可以发现和总结:clone方法复制的是栈中的引用形成一个新的对象。