为什么ArrayList具有克隆方法

时间:2019-03-14 19:23:09

标签: java arraylist

我不确定我是否了解clone()ArrayList的用途。

有很多方法可以制作ArrayList的浅表副本,我至少知道两种:

List<Integer> L1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
List<Integer> L1_copy = new ArrayList<>(L1);
List<Integer> L1_copy2 = List.copyOf(L1);   // inmutable but solve by below:
List<Integer> L1_copy3 = new ArrayList<>(List.copyOf(L1));

令人惊讶的是,它返回一个Object,而不是ArrayList,而且我不得不垂头丧气:

ArrayList<Integer> AL1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
ArrayList<Integer> AL1_copy = (ArrayList<Integer>) AL1.clone();

为什么设计为以Object的形式返回? 与其他浅拷贝方法相比,使用克隆有什么优势?

3 个答案:

答案 0 :(得分:2)

由于clone()方法的存在,我认为没有额外的优势。在基元的情况下,它相当于深层副本。 另外,除了构造函数之一外,我不知道Java中的许多方法,在该方法中,您将Collection作为构造函数的参数进行传递。 它还实现了Cloneable接口,我认为它类似于标记接口。 它返回Object,因为它是所有类的超类,返回它不会破坏代码。

答案 1 :(得分:2)

键入是ArrayList在Java 5之前编写的结果。在Java 5之前,重写方法的返回类型必须与被重写的方法相同(是 invariant ) 。如今,由于方法返回类型可以是专门的(协变),因此,如果要重写ArrayList,则应使用ArrayList作为返回类型来编写。

但是,这里存在一个深层的问题,即虽然实现可以专门化clone()的返回类型,但类型系统并未完全表达类型关系。最好是Java只能少量支持的“自我”类型。这使您深入了解打字理论。例如,请参见:Java self-typed methods: cannot safely cast to actual type

从实用程序的角度来看,正如其他人所说,Cloneable并不是一个非常有用的API。在实践中,关于一个人希望如何复制单个API以使其适合所有这些细节的方式,往往会有太多细节。

答案 2 :(得分:0)

通常,公共clone()方法支持多态。您可以在超类类型的引用上调用它,以克隆任何子类类型的对象。

  

为什么设计它作为对象返回?

协变返回类型是在Java 5中引入的。ArrayList是在Java 2中引入的。

ArrayList不是最终课程。修改其返回类型以返回ArrayList可能会破坏第三方子类。

  

与其他浅拷贝方法相比,使用克隆有何优势?

多态性。