了解非最终类的克隆方法

时间:2015-07-21 07:45:30

标签: java clone

我正在阅读J. Bloch的有效java,现在我在第39节(制作防御性副本)。他提到通过clone方法制作防御性副本并不好,因为:

  

另请注意,我们没有使用Date的克隆方法来制作   防御性的副本。由于Date是非最终的,因此克隆方法不是   保证返回一个类为java.util.Date的对象:它可以   返回专门为其设计的不可信子类的实例   恶意恶作剧。

强调的声明对我来说并不明显。实际上,让我们与javadocs进行交流。没有关于创建子类的任何参考。我们唯一可以肯定的是:

  

此方法创建此对象的类 的新实例   准确地初始化其所有字段的内容   该对象的相应字段,好像通过赋值;内容   这些田地本身并没有被克隆。

那么为什么J. Bloch说它可以创建 子类 ?你无法解释它是如何从javadoc中解释的(我自己也看不到这一点)。

1 个答案:

答案 0 :(得分:3)

它隐含在Javadocs的引用中:“this”对象的类可以是引用该对象的变量的声明类型的子类(由于多态性)。 clone方法受到保护,因此可以在某个类的子类中调用它。

public class Test {
    public static void main(String[] args) throws Exception {
        Foo foo = new Bar();
        Foo copyOfFoo = createCopyOfFoo(foo);
        System.out.println(copyOfFoo);
    }


    private static Foo createCopyOfFoo(Foo foo) throws CloneNotSupportedException {
        Foo clone = (Foo) foo.clone();
        return clone;
    }
}

class Foo implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Bar extends Foo {
    private int x = 1;

    @Override
    public String toString() {
        return "Bar [x=" + x + "]";
    }
}

<强>输出:

  

Bar [x = 1]