我试图了解Object类的clone()方法的工作原理。 Object类中的注释表示' 此方法执行"浅拷贝"这个对象,而不是"深拷贝" 。操作'
以下是我对Shallow& amp;的理解深拷贝..
浅拷贝尽可能少复制。浅的副本 集合是集合结构的副本,而不是元素。 通过浅拷贝,两个集合现在共享个人 元件。
深层副本重复所有内容。集合的深层副本是两个 包含原始集合中所有元素的集合 复制。
因此,如果我克隆一个Object并修改它在克隆上的任何可变元素,那么同样应该反映在创建克隆的第一个对象上,因为它们共享相同的内存。为了测试这个,我创建了3个类......
一个简单的pojo ..
package test.clone;
import java.util.Arrays;
public class Misc implements Cloneable{
private String value;
public Misc(String value) {
super();
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "Misc [value=" + value + "]";
}
protected Misc clone() throws CloneNotSupportedException{
return (Misc)super.clone();
}
}
需要克隆的类..
package test.clone;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Victim implements Cloneable{
private String name = "Renjith";
private String[] educationList = {"EDU_1", "EDU_2", "EDU_3", "EDU_4"};
private Misc[] miscList = {new Misc("1"), new Misc("2")};
private List<Misc> miscList2 = new ArrayList<Misc>(Arrays.asList(miscList));
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getEducationList() {
return educationList;
}
public void setEducationList(String[] educationList) {
this.educationList = educationList;
}
protected Victim clone() throws CloneNotSupportedException{
return (Victim)super.clone();
}
public Misc[] getMiscList() {
return miscList;
}
public void setMiscList(Misc[] miscList) {
this.miscList = miscList;
}
public List<Misc> getMiscList2() {
return miscList2;
}
public void setMiscList2(List<Misc> miscList2) {
this.miscList2 = miscList2;
}
@Override
public String toString() {
return "Victim [name=" + name + ", educationList="
+ Arrays.toString(educationList) + ", miscList="
+ Arrays.toString(miscList) + ", miscList2=" + miscList2 + "]";
}
}
进行克隆的主要类......和修改......
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Victim victim = new Victim();
System.out.println(victim);
Victim secondVictim = victim.clone();
String[] educationList = {"EDU_1_mod", "EDU_2_mod", "EDU_3_mod", "EDU_4_mod"};
Misc[] miscList = {new Misc("3"), new Misc("4")};
List<Misc> miscList2 = new ArrayList<Misc>(Arrays.asList(miscList));
secondVictim.setEducationList(educationList);
secondVictim.setMiscList(miscList);
secondVictim.setMiscList2(miscList2);
System.out.println(secondVictim);
System.out.println(victim);
}
}
我期待输出如下......
受害者[name = Renjith,educationList = [EDU_1,EDU_2,EDU_3,EDU_4], miscList = [Misc [value = 1],Misc [value = 2]],miscList2 = [Misc [value = 1], 杂项[value = 2]]]受害者[name = Renjith,educationList = [EDU_1_mod, EDU_2_mod,EDU_3_mod,EDU_4_mod],miscList = [Misc [value = 3],Misc [value = 4]],miscList2 = [Misc [value = 3],Misc [value = 4]]]受害者 [name = Renjith,educationList = [EDU_1,EDU_2,EDU_3,EDU_4], miscList = [杂项[值= 3 ],杂项[值= 4 ]],miscList2 = [杂项[值= 3 ], 其他[值= 4 ]]]
但我得到了......
受害者[name = Renjith,educationList = [EDU_1,EDU_2,EDU_3,EDU_4], miscList = [Misc [value = 1],Misc [value = 2]],miscList2 = [Misc [value = 1], 杂项[value = 2]]]受害者[name = Renjith,educationList = [EDU_1_mod, EDU_2_mod,EDU_3_mod,EDU_4_mod],miscList = [Misc [value = 3],Misc [value = 4]],miscList2 = [Misc [value = 3],Misc [value = 4]]]受害者 [name = Renjith,educationList = [EDU_1,EDU_2,EDU_3,EDU_4], miscList = [Misc [ value = 1 ],其他[值= 2 ]],miscList2 = [其他[值= 1 ], 其他[值= 2 ]]]
任何人都可以告诉我这有什么问题吗?
我已经完成了Understanding Object.clone() in Java,但仍然无法理解......
答案 0 :(得分:2)
您没有修改列表/数组,而是用新引用替换它们。尝试像这样更新你的setter:
public void setMiscList(Misc[] miscList) {
this.miscList[0] = miscList[0];
this.miscList[1] = miscList[1];
}
public void setMiscList2(List<Misc> miscList2) {
this.miscList2.set(0, miscList2.get(0));
this.miscList2.set(1, miscList2.get(1));
}
这应修改共享对象,从而产生预期的输出。