super.clone()查询?

时间:2011-12-28 11:34:19

标签: java

请向我澄清以下问题。

  1. super.clone()执行深层复制还是浅层复制?
  2. 在下面的示例中,为什么我们不需要将类CompositeObjCloneMe作为可复制的?尝试克隆cObj对象时是否会克隆CloneMe? 注意:即使将CompositeObjCloneMe设为可克隆也不会对输出产生任何影响。
  3. 为什么输出表现得像浅层复制(Not deep coppying),因为程序正在设置类的原始值(setCObjValue = 100)? (原始字段被深深复制)
  4. 它是不可变的对象&&原语本身就被深深复制了?

    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);
            }
        }
    }
    
  5. 输出:100 100

2 个答案:

答案 0 :(得分:1)

1)javadoc救援:

  

[...]因此,此方法执行此对象的“浅拷贝”,而不是   “深层复制”操作。

2)因为clone不会递归调用clone。这是一个浅薄的克隆。它只是创建一个与原始对象具有相同引用的新对象,以及原始字段的副本。

3)我不明白你的意思。原始人没有被深深复制。他们没有引用任何东西,所以没有什么可以复制的。

答案 1 :(得分:1)

JB Nizet已经回答了第一个和第二个问题。

对于您的第三个问题,realObjcloneObj都引用了相同的CompositeObjCloneMe实例。克隆真实对象时,克隆对象的CompositeObjCloneMe字段cObj将与realObj中的实例相同。因此,通过调用cObj来更改realObj realObj.setCObjValue(100);也会影响cloneObj

所以输出正是预期的结果。

注意:您可以使用调试器并查看realObjcloneObj

字段来轻松验证这一点

如果你想要深度克隆,你应该调用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();。否则,如果子类也想要实现克隆,则必须复制类中的所有逻辑。

一些额外的文档:WikipediaCodeguru