克隆方法存在时复制构造函数的用途?

时间:2014-07-31 11:58:48

标签: java arraylist reference clone copy-constructor

来自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 ConstructorClone Method。如果有任何Java对象有其中任何一个,但不是两个,那么我没有意识到这一点。不过,我的问题是针对ArrayList的案例。

那么,它的目的是什么?在哪种情况下,您更喜欢使用ArrayList的Copy Constructor而不是Clone Method

PS:如果有人对Copy Constructor的{​​{1}}和Clone Method的确切代码进行比较,那就太棒了。

3 个答案:

答案 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
  • 复制构造函数具有处理泛型的优点(如Stephen C所示)。

以下是一些有趣的资料来源:


然后,您已经要求提供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