Java clone()方法

时间:2015-05-06 13:44:36

标签: java

我读过J.Bloch的Effective Java,这里写道:

  

如果您设计了一个继承类,请注意,如果您不选择   为了提供一个表现良好的受保护克隆方法,它将是   子类不可能实现Cloneable。

我有A级:

public class A{}

扩展A类的B类:

public class B extends A implements Cloneable {

}

所以在这种情况下,我无法覆盖clone()方法?如果是,请解释原因。

3 个答案:

答案 0 :(得分:2)

在您的情况下,您可以覆盖clone()

public class A {
}

public class B extends A implements Cloneable {

    @Override
    public B clone() throws CloneNotSupportedException {
        return (B) super.clone();
    }
}

仍然有一个有效的克隆机制 - 当你陈述implements Cloneable时,你就说实话了。

然而,打破这一承诺所需要的只是给A一个private变量。

public class A {
    private int a;
}

现在你的承诺被打破 - 除非A实施clone,在这种情况下你可以使用super.clone()

public class A {

    private int a;

    @Override
    public A clone() throws CloneNotSupportedException {
        A newA = (A) super.clone();
        newA.a = a;
        return newA;
    }
}

public class B extends A implements Cloneable {

    private int b;

    @Override
    public B clone() throws CloneNotSupportedException {
        B newB = (B) super.clone();
        newB.b = b;
        return newB;
    }
}

基本上 - 正如Joshua Bloch所说 - 如果你不实施clone,你的子类也不能(通常)。

答案 1 :(得分:1)

Cloneableclone()几乎已被弃用,因此无论如何都不重要。但是,由于clone()始终应该调用super.clone(),如果超类实现错误,子类也无法修复它。

与无法覆盖clone()无关,它只是不会导致正确的实施。

答案 2 :(得分:0)

当然,您可以实施B.clone()

J. Bloch提到的问题是(IIRC),没有良好的A.clone()方法,A中的私有字段无法在B中正确克隆。简单示例:

public class A {
  private String myText;
  public A (String myText) {
    this.myText = myText;
  }
  public String getExtendedText() {
    return "Hello something " + myText;
  }
}

public class B extends A implements Cloneable {
    private int someValue;
    // getter/setter

    public clone() {
        // how can you now provide a good clone with A.myText being cloned?
    }    
}