一般建议:使用
复制构造函数。事实上,只有类本身知道如何创建自己的克隆。没有任何类能够克隆另一个类的实例。思路如下:
public class Foo {
public List<Bar> bars = new ArrayList<Bar>();
private String secret;
public Foo(Foo that) {
this.bars = new ArrayList<Bar>();
for (Bar bar:that.bars) {
this.bars.add(new Bar(bar));
}
this.secret = new String(that.secret);
}
}
如果我们想克隆一个foo
,我们只需基于foo
创建一个新的对象:
Foo clonedFoo = new Foo(foo);
这是克隆实例的推荐方法。
复制构造函数与继承很好地配合。考虑一个子类。
public ChildFoo extends Foo {
private int key;
public ChildFoo(ChildFoo that) {
super(that);
this.key = that.key;
}
}
Foo
有一个复制构造函数,而ChildFoo
只是从自己的复制构造函数中调用它。
你的例子是可行的,但不建议使用。会发生什么:
Foo a = new Foo();
ChildFoo b = new ChildFoo(a);
这将需要在ChildFoo上添加构造函数,例如:
public ChildFoo(Foo that) {
// call the copy constructor of Foo -> no problem
super(that);
// but how to initialize this.key? A Foo instance has no key value!
// Maybe use a default value?
this.key = 0;
}
从技术上讲,这不是一个挑战,但b并非a
的克隆,因为这两个对象的类型不同。因此,这个例子不是“克隆”。
List
,您将使用哪个类构造函数(ArrayList、LinkedLink等)? - Steve KuoList
接口没有 clone 方法,那你怎么办呢?我们不能克隆 接口。 - Andreas Dolk