对于具有数组字段的类,Josh 说如果克隆方法仅返回 super.clone(),则生成的类实例将在原始字段中具有正确的值,但其数组字段将引用与原始类实例相同的数组。修改原件将破坏不变量,反之亦然。
他使用了自定义 Stack 实现的示例,我使用的是一个简单的 Student 类
class Student implements Cloneable {
private String name;
private int age;
private int[] marks = {90, 70, 80};
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMarks(int[] marks) {
this.marks = marks;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}
@Override
public String toString() {
return "Student - Name : " + name + " Age : " + age + " Marks : " + Arrays.toString(marks);
}
}
请注意:我没有在我的克隆方法覆盖中的数组字段上调用 clone()。
然后我做了:
public class CloningDemo {
public static void main(String[] args) {
Student s1 = new Student("Mohit", 30);
Student s2 = null;
try {
s2 = s1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println("S1 : " + s1);
System.out.println("S2 : " + s2);
System.out.println("Updating the clone...");
s2.setName("Rohit");
s2.setAge(29);
s2.setMarks(new int[]{10, 29, 30});
System.out.println("S1 : " + s1);
System.out.println("S2 : " + s2);
System.out.println("Updating the array elements in Original...");
s1.setMarks(new int[]{10, 10, 10});
System.out.println("S1 : " + s1);
System.out.println("S2 : " + s2);
}
}
输出:
S1 : Student - Name : Mohit Age : 30 Marks : [90, 70, 80]
S2 : Student - Name : Mohit Age : 30 Marks : [90, 70, 80]
Updating the clone...
S1 : Student - Name : Mohit Age : 30 Marks : [90, 70, 80]
S2 : Student - Name : Rohit Age : 29 Marks : [10, 29, 30]
Updating the array elements in Original...
S1 : Student - Name : Mohit Age : 30 Marks : [10, 10, 10]
S2 : Student - Name : Rohit Age : 29 Marks : [10, 29, 30]
我想知道更改原始实例中的数组也会更改我的克隆中的数组,因为我在上面提到“数组字段将引用与原始实例相同的数组”
通过我的克隆实现,我也应该看到克隆 s2 的变化。正确的实现应该是:
@Override
protected Student clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();
student.marks = marks.clone(); // I am not doing this in my code.
return student;
}
我误解了这个吗?有人可以解释发生了什么吗?
谢谢
~莫希特