我有点像Java N00B,但我对克隆感到非常困惑。
考虑以下不正确的类
class blah {
public blah(Collection<Integer> c){
member_collection = c.clone(); //the clone here is defensive
}
private final Collection<Integer> member_collection;
}
我认为我想要做的是明确的。
我理解为什么找不到clone()符号:clone不是任何可能的Collection中的公共方法。但是,在我想要使用它的任何具体类中,我想告诉编译器。
我确定我不是第一个想要克隆泛型集合的人,但我看过的教程只解释了为什么你不能克隆集合,而不是如何解决这个问题。我尝试过使用getClass()和强制转换的hacky东西,但是那些通常需要我制作丑陋的try-catch块,并且很难确保一次初始化(指针member_collection)是最终的!
我真正想做的是以某种方式将这些信息放入类型中。有没有一个很好的方法来做到这一点?
谢谢!
答案 0 :(得分:3)
你最好这样复制:
public class Blah {
private final Collection<Integer> collection;
public Blah(Collection<Integer> collection) {
this.collection = new ArrayList<Integer>(collection);
}
}
或者像这样:
public class Blah {
private final Collection<Integer> collection = new ArrayList<Integer>();
public Blah(Collection<Integer> collection) {
this.collection.addAll(collection);
}
}
这与您正在尝试的内容相同,并保证保留给定Collection
的任何顺序。
编辑:如果你绝对需要它与给你的实现相同,并且你不想重新考虑你的设计,那么你可以做一些hacky反射的东西和把它放在static
方法中。
public class Blah {
private final Collection<Integer> collection;
public Blah(Collection<Integer> collection) {
this.collection = clone(collection);
}
@SuppressWarnings("unchecked")
private static <T> T clone(T t) {
try {
Method cloneMethod = t.getClass().getDeclaredMethod("clone");
return (T) cloneMethod.invoke(t);
} catch (Exception ex) {
// TODO Log ex
return null;
}
}
}
具体集合必须实现clone
作为公共方法,因此这应该适用于大多数公共方法。对于那些没有的人,null
。你可能只想重新抛出你得到的任何异常。
答案 1 :(得分:2)
由于您是Java新手,我很遗憾地告诉您Java中的clone()
和Cloneable
已被破坏,依赖它们并不是一个好主意。但是,如果你只想clone()
该死的东西,你可以:
ObjectUtils.clone()
/ ObjectUtils.cloneIfPossible()
(不是强类型但合理安全)。答案 2 :(得分:0)
你可以写member_collection = new ArrayList<Integer>(c)
。
这将创建一个浅表副本。