ArrayList的深层副本 - 方法clone()不可见

时间:2014-12-12 21:31:52

标签: java

我正在尝试实现我自己的这个对象的深层副本:

public class Column<T extends Cloneable>
{

    private final ArrayList<T> values;

    private String name;

    // ...

}

这就是克隆这个类的实例的方法:

Column<String> column     = new Column<String>();
// ...
Column<String> columnCopy = column.copy();

这是我正在尝试实现的方法(假设方法clone()是正确的ovverridden):

public Column<T> copy()
{
    ArrayList<T> valuesCopy = new ArrayList<T>();

    for (T value : values)
        valuesCopy.add(value.clone()); // The method clone() from the type Object is not visible

    return new Column<T>(name, valuesCopy);
}

如果值类型为T,定义为T extends Cloneable,为什么方法clone()不可见?

感谢。

4 个答案:

答案 0 :(得分:5)

由于以下原因,您的代码无法看到clone方法。

  1. clone方法为protected in Object
  2. Cloneable interface是一个标记界面,不保证public clone方法(或任何方法)的存在。
  3. 您正在使用带有上限T的泛型类型参数Cloneable,但在类型擦除之后,这只变为Cloneable,因此编译器只能假定Object方法存在,clone受到保护,因此无法以这种方式调用。

答案 1 :(得分:1)

Cloneable中没有clone()。

  

请注意,此接口包含克隆   方法。因此,仅仅通过克隆对象是不可能的   因为它实现了这个接口。即使是   克隆方法是反射性调用的,不能保证它   会成功的。

答案 2 :(得分:1)

clone方法由于其他原因而有几个原因不起作用。

有几种方法可以自己执行深层复制,或者通过逐字迭代对象并将每个元素复制到“克隆”对象的新元素中,或者更快捷的方法是serialize对象然后deserialize它...因为这将做一个精确的深层复制。

这是一个快速示例,它接受任何对象并返回完全重复的对象。确保你回到预期的类型。

public static Object makeClone(final Object obj) 
                            throws IOException, ClassNotFoundException {

        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
        java.io.ObjectOutputStream obj_out = new java.io.ObjectOutputStream(bos);
        obj_out.writeObject(obj);

        java.io.ByteArrayInputStream bis = 
                        new java.io.ByteArrayInputStream(bos.toByteArray());
        java.io.ObjectInputStream obj_in = new java.io.ObjectInputStream(bis);

        @SuppressWarnings("unchecked")
        Object newObj = obj_in.readObject();

        bos.close();
        bis.close();
        obj_out.close();
        obj_in.close();

        return newObj;
}

答案 3 :(得分:0)

对不起,我确信Cloneable界面不仅仅是一个标记界面。

您如何看待我自己的解决方案? (我不确定它是否正确)

public class Column<T extends Copyable<T>> implements Cloneable
{

    private final ArrayList<T> values;

    private String name;

    // ...

    public Column<T> clone()
    {
        ArrayList<T> valuesCopy = new ArrayList<T>();

        for (T value : values)
            valuesCopy.add(value.clone());

        return new Column<T>(name, valuesCopy);
    }

}

public interface Copyable<T> extends Cloneable
{

    public T clone();

}