Java 为什么ArrayList有克隆方法

Java 为什么ArrayList有克隆方法,java,arraylist,Java,Arraylist,我不确定我是否理解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); // inmuta

我不确定我是否理解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));
为什么它被设计为作为一个对象返回?
与其他浅层复制方法相比,使用克隆有什么优势?

我认为克隆方法的存在并没有带来额外的优势。在原语的情况下,它将等同于一个深度副本。 另外,我不知道Java中有这么多方法,除了构造函数方法,在构造函数中,您将集合作为参数传递给构造函数。 它还实现了可克隆的接口,我认为它就像一个标记接口。
它返回Object,因为它是所有类的超类,返回它不会破坏代码。

我认为克隆方法的存在并没有额外的优势。在原语的情况下,它将等同于一个深度副本。 另外,我不知道Java中有这么多方法,除了构造函数方法,在构造函数中,您将集合作为参数传递给构造函数。 它还实现了可克隆的接口,我认为它就像一个标记接口。
它返回Object,因为它是所有类的超类,返回它不会破坏代码。

一般来说,公共克隆方法支持多态性。您可以在超类类型的引用上调用它,以克隆任何子类类型的对象

为什么它被设计为作为一个对象返回

Java5中引入了协变返回类型。ArrayList是在Java2中较早引入的

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

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


多态性

一般来说,公共克隆方法支持多态性。您可以在超类类型的引用上调用它,以克隆任何子类类型的对象

为什么它被设计为作为一个对象返回

Java5中引入了协变返回类型。ArrayList是在Java2中较早引入的

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

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


多态性

该类型是在java 5之前编写ArrayList的结果。在Java5之前,重写方法的返回类型必须与被重写的方法的返回类型相同。今天,由于方法返回类型可以被专门化,并且是协变的,所以如果要重写ArrayList,那么应该使用ArrayList作为返回类型来编写它

然而,这里有一个深层次的问题,即虽然实现可以专门化克隆的返回类型,但类型系统并没有完全表达类型关系。更好的方法是使用self类型,java只支持少量的self类型。这让你对打字理论有了更深的了解。例如,请参见:


正如其他人所说,从实用程序的角度来看,Cloneable并不是一个非常有用的API。在实践中,对于如何让一个拷贝为一个API工作以适应所有这些细节,往往有太多的细节。

这种类型是在java 5之前编写ArrayList的结果。在Java5之前,重写方法的返回类型必须与被重写的方法的返回类型相同。今天,由于方法返回类型可以被专门化,并且是协变的,所以如果要重写ArrayList,那么应该使用ArrayList作为返回类型来编写它

然而,这里有一个深层次的问题,即虽然实现可以专门化克隆的返回类型,但类型系统并没有完全表达类型关系。更好的方法是使用self类型,java只支持少量的self类型。这让你对打字理论有了更深的了解。例如,请参见:


正如其他人所说,从实用程序的角度来看,Cloneable并不是一个非常有用的API。在实践中,对于如何让一个拷贝为一个API工作以适应所有这些细节,往往有太多的细节。

它正在实现接口,这在某一点上肯定有人认为是个好主意。这不是一个非常有用的界面。这很有趣,有没有不可克隆的对象?当然。许多类不实现可克隆性。此方法如果来自对象类。如果您想确切地了解Arraylist中如何实现cloneable,请参阅javadoc,这是Arraylist for Java8的源代码,它似乎只是在后端调用了Arrays.copyOf。它正在实现接口,这在某一点上肯定有人认为是个好主意。这不是一个非常有用的界面。这很有趣,有没有不可克隆的对象?当然。许多类不实现可克隆性。此方法如果来自对象类。如果您需要,请参阅javadoc
为了了解Arraylist中如何实现cloneable,下面是Arraylist for Java8的源代码,它似乎只是在后端调用了Arrays.copyOf。虽然它是在对象中声明的,但对象中的一个是受保护的。ArrayList公开该方法并提供其自己的实现,这是因为该类实现了Cloneable。即使它没有覆盖它,它仍然可用。如果它没有覆盖它,该方法将受到保护,因此不公开。hmm。谢谢我将编辑答案。我忘记了这个细节。虽然它是在Object中声明的,但Object中的那个是受保护的。ArrayList公开该方法并提供其自己的实现,这是因为该类实现了Cloneable。即使它没有覆盖它,它仍然可用。如果它没有覆盖它,该方法将受到保护,因此不公开。hmm。谢谢我将编辑答案。我忘了这个细节。
ArrayList<Integer> AL1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
ArrayList<Integer> AL1_copy = (ArrayList<Integer>) AL1.clone();