Java Deep Clone - 克隆ArrayList中的每个元素(如果Cloneable,无论类型如何)

时间:2014-03-12 17:59:11

标签: java arraylist casting clone

我有一个ArrayList a,它可以包含任何类型的对象。然后我需要循环遍历ArrayList的元素。如果元素实现Cloneable,我需要克隆元素(意味着复制它并在内存中赋予它自己的位置)并将克隆元素添加到ArrayList b。问题在于铸造。我需要转换为正确的对象类型,然后调用clone()。 (因为Object中的clone()受到保护。)

在下面的代码中,我设法用一堆if语句来做到这一点。在每个元素上,我说如果Cloneable,然后嵌套在if语句中我有更多if语句,检查正确类型的实例。当程序找到正确的类型时,它会转换和克隆。所有这些代码都有效,但是我想要一种方法来进行转换然后克隆()而不使用这些if语句,因为可能还有我不知道的类。有没有办法做到这一点? (我可以使用Class.cast()进行转换,但是我没有成功调用clone()来进行此类转换。)

我试图序列化数组列表,实现我自己的接口(使用clone()方法),并调用复制构造函数。这些都不适用于所有情况。接近我可以说,铸造然后克隆是使它工作的唯一可靠方法。如果有一种方法可以在不指定确切类的情况下进行强制转换和克隆,那么这将适用于所有情况。否则,我很难过,需要另一个解决方案。 (如果有办法遍历对象中的每个字段而不管可访问性,那么这也可能有用。)

这是我的代码:

// Establish variables
TestClass t = new TestClass();
TestClass u = new TestClass(1);
Point p = new Point();
Point q = new Point(1, 2);

// Set up ArrayList a
ArrayList a = new ArrayList();
a.add(t);
a.add(u);
a.add(p);
a.add(q);

// Get number of elements in a
int n = a.size();

// Set up ArrayList b
ArrayList b = new ArrayList();

// Clone all Cloneable elements from a into b
for (int i = 0; i < n; i++)
    if (a.get(i) instanceof Cloneable)
        if (a.get(i) instanceof TestClass)
            b.add(((TestClass)a.get(i)).clone());
        else if (a.get(i) instanceof Point)
            b.add(((Point)a.get(i)).clone());
    //ISSUE: I need to be able to cast and then clone based on the class a.get(i) represents, to avoid these if statements.

// Change initial variables. They change in ArrayList a (due to referencing the same memory) but not b
t.i = 2;
u.i = 3;
p.x = 3;
p.y = 4;
q.x = 5;
q.y = 6;

System.out.println(a);
System.out.println(b);

TestClass和Point是我写过的类。他们实现了Cloneable。

感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:1)

我认为你可以使用反射

来做到这一点
if (a.get(i) instanceof Cloneable) {
  Cloneable c = (Cloneable) a.get(i);
  try {
    Method cloneMethod = c.getClass().getMethod("clone", new Class<?>[] {});
    cloneMethod.setAccessible(true);
    Object clone = cloneMethod.invoke(c, new Object[] {});
    b.add(clone);
  } catch (Exception e) {
    // Add real error handling.
    e.printStackTrace();
  }
} else {
  // It isn't cloneable.
}

答案 1 :(得分:1)

Java中的整个克隆机制基本上已经破解。 请参阅示例http://www.artima.com/intv/issues3.html

你可以使用一个具有所有功能的库(http://code.google.com/p/cloning/ - (Deep clone utility recomendation信用到Cojones)或创建一个自己的界面,如

public interface Copyable<T> {
 T copy();
}

让您需要的所有类都实现该接口。如果您知道它是哪个类,您通常可以像

一样使用它
SomeClass a = new SomeClass();
SomeClass clone = a.copy();

或者,如果您只知道它是可复制的:

Copyable<?> copy = x.copy();

但在大多数情况下,最好使用现有解决方案,就像上面的图书馆一样。

(编辑:不使用javas自己的克隆东西总是最好的选择:))