请向我澄清以下问题。
super.clone()
执行深层复制还是浅层复制?CompositeObjCloneMe
作为可复制的?尝试克隆cObj
对象时是否会克隆CloneMe
?
注意:即使将CompositeObjCloneMe
设为可克隆也不会对输出产生任何影响。setCObjValue = 100
)? (原始字段被深深复制)它是不可变的对象&&原语本身就被深深复制了?
class CloneMe implements Cloneable {
private CompositeObjCloneMe cObj;
public CloneMe() {
cObj = new CompositeObjCloneMe();
}
public void setCObjValue(int myOwnDt) {
this.cObj.setObj(myOwnDt);
}
public int getCObjValue() {
return this.cObj.getObj();
}
//Clone
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class CompositeObjCloneMe {//implements Cloneable{
private int value = 20;
public void setObj(int i){
value = i;
}
public int getObj(){
return value;
}
// public Object clone() throws CloneNotSupportedException{
// return super.clone();
// }
}
public class CloneTest {
public static void main(String arg[]) {
CloneMe realObj = new CloneMe();
try {
CloneMe cloneObj = (CloneMe) realObj.clone();
realObj.setCObjValue(100);
System.out.println(realObj.getCObjValue() + " " + cloneObj.getCObjValue());
} catch (CloneNotSupportedException cnse) {
System.out.println("Cloneable should be implemented. " + cnse);
}
}
}
输出:100 100
答案 0 :(得分:1)
1)javadoc救援:
[...]因此,此方法执行此对象的“浅拷贝”,而不是 “深层复制”操作。
2)因为clone不会递归调用clone。这是一个浅薄的克隆。它只是创建一个与原始对象具有相同引用的新对象,以及原始字段的副本。
3)我不明白你的意思。原始人没有被深深复制。他们没有引用任何东西,所以没有什么可以复制的。
答案 1 :(得分:1)
JB Nizet已经回答了第一个和第二个问题。
对于您的第三个问题,realObj
和cloneObj
都引用了相同的CompositeObjCloneMe
实例。克隆真实对象时,克隆对象的CompositeObjCloneMe
字段cObj
将与realObj
中的实例相同。因此,通过调用cObj
来更改realObj
realObj.setCObjValue(100);
也会影响cloneObj
。
所以输出正是预期的结果。
注意:您可以使用调试器并查看realObj
和cloneObj
如果你想要深度克隆,你应该调用super.clone并复制非原始字段。 E.g。
public Object clone() throws CloneNotSupportedException {
CloneMe clone = (CloneMe)super.clone();
clone.cObj = ...;//make a clone, a new instance, ...
return clone;
}
请致电super.clone
来创建您将返回的对象,而不是简单地致电CloneMe clone = new CloneMe();
。否则,如果子类也想要实现克隆,则必须复制类中的所有逻辑。