来自this SO-question, answers and comments我知道
的结果ArrayList<Object> listClone = new ArrayList<Object>(list);
与相比,在幕后做了额外的一步
@SuppressWarnings("unchecked")
ArrayList<Object> listClone = (ArrayList<Object>)list.clone();
但结果是一样的。那么,当我们有Copy Constructor
时,为什么还有Clone Method
?
注意:此问题主要针对ArrayList
,因为我知道它同时包含Copy Constructor
和Clone Method
。如果有任何Java对象有其中任何一个,但不是两个,那么我没有意识到这一点。不过,我的问题是针对ArrayList
的案例。
那么,它的目的是什么?在哪种情况下,您更喜欢使用ArrayList的Copy Constructor
而不是Clone Method
?
PS:如果有人对Copy Constructor
的{{1}}和Clone Method
的确切代码进行比较,那就太棒了。
答案 0 :(得分:3)
那么,它的目的是什么?
查看复制构造函数的签名:
ArrayList(Collection<? extends E> c)
它从任何集合构建一个列表;例如一个LinkedList
,任何类型的Set
等等。
相比之下,您只能clone()
来自另一个ArrayList
的{{1}}。
现在毫无疑问&#34;问题&#34;一般来说ArrayList
。但是对于(至少)标准的非并发集合类,克隆与复制构造函数一样...模块化它完成了工作;往上看。对于这些类,clone()
方法被定义为返回浅拷贝;看到各自的类javadocs。
如果有人拥有复制构造函数和Java#ArrayList的克隆方法的确切代码进行比较,那就太棒了。
Google是你的朋友。谷歌的clone()
。
(我更喜欢Grepcode网站。它有多个版本的代码,以及用于导航代码,包层次结构,类层次结构甚至定义/使用关系的漂亮UI。)
答案 1 :(得分:1)
我知道有一点不同。复制构造函数采用Collection,而不仅仅是Arraylist。与复制构造函数相比,它更像是“将所有内容填充到新的ArrayList”构造函数中。元素的顺序也由给定集合的迭代器决定。
另一方面,.clone()方法从给定的ArrayList中创建一个新的ArrayList。
这两种情况有所不同的一种情况:
List a=new ArrayList();
List l=new LinkedList();
List a2 = new ArrayList(a); //returns ArrayList
List a3 = new ArrayList(l); //returns ArrayList
List a4 = a.clone(); //returns ArrayList
List a5 = l.clone(); //returns LinkedList
答案 2 :(得分:1)
据我所知,这取决于你的设计意图,你会使用哪一种,但clone()
方法通常被认为是破碎的。这可能是设计师添加适当的复制构造函数的好理由。
以下是一些优点和缺点:
clone()
方法被认为会引发问题。首先,默认情况下,不清楚是表示深拷贝还是浅拷贝。如果你在层次结构中调用super.clone()
,你可能最终得到一个可变对象的浅拷贝,这不是你的意图。 clone()
作为数组,因为它更快。 Cloneable
目前尚不清楚。如果某些内容为Cloneable
,则可能仍然不清楚您真正可以使用哪些方法,因为它没有公开clone()
方法,也没有Object
。 以下是一些有趣的资料来源:
然后,您已经要求提供ArrayList复制构造函数的源代码并克隆:
ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
public Object clone() {
try {
@SuppressWarnings("unchecked")
ArrayList<E> v = (ArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
来自CodeGrep。