【问题标题】:Is there any advantage of using array.clone() above manual copy在手动复制上面使用 array.clone() 有什么好处吗
【发布时间】:2013-05-14 07:55:01
【问题描述】:

使用有什么缺点或优点

public Loteria( int[] liczby) {
   this.liczby = liczby.clone();
}

代替:

public Loteria( int[] liczby) {
   this.liczby = new int[liczby.length];
   for(int i = 0....)
       this.liczby[i] = liczby[i];
}

【问题讨论】:

标签: java clone


【解决方案1】:

这两种方法都会创建数组元素的浅拷贝,这意味着数组中的元素仍将相互引用。如果您想要副本,请坚持array.clone()

  • 更具可读性
  • 代码更少,使用标准 Java API。

深拷贝数组

Java 6+

this.liczby = Arrays.copyOf(liczby, liczby.length);

旧版本

System.arraycopy(liczby, 0, this.liczby, 0, liczby.length);

测试

Object[] original = { new Object(), null };
Object[] copy = new Object[2];
System.arraycopy(original, 0, copy, 0, original.length);
Object[] copy2 = Arrays.copyOf(original, original.length + 1);
copy2[1] = 2;
System.out.println(original[1]); // null
System.out.println(copy2[1]); // 2

【讨论】:

  • 这是一个基元数组。
  • 当然System.arraycopy 产生相同的结果-Arrays.copyOf 在后台调用它(正如我在对问题的评论中已经说过的那样)。你可以看到源here。在这一点上,您似乎只是对“深拷贝”的含义感到困惑。基本上,深拷贝也会拷贝底层对象,因此将元素与引用相等 (==) 进行比较是错误的。
  • 重点是,它不是深度克隆。没有人说这些数组是相同的引用。如何解释为什么用copy = (Object[])original.clone(); 替换您的示例会产生相同的结果。
  • 1) 您的测试仅显示浅拷贝。 “两个输出都是 2”只有在没有复制数组本身的情况下才会发生。数组被复制,但元素对象不是。 originalcopycopy2 的第一个元素都是对同一个 Object 的引用。 2)您链接的文章无关紧要,因为我的示例仅使用== 来比较Objects,而不是装箱的原语(就像您出于某种原因决定的那样)。 3) 在没有循环的情况下深度克隆数组的唯一方法是使用序列化(这在 fgb 链接的一篇文章中进行了讨论)。
【解决方案2】:

关于你的手写版本,

优点:让您可以更好地控制代码

缺点:更难阅读和维护。与通用 clone() 相比没有性能优势。

只要你可以,我会选择clone()

【讨论】:

    【解决方案3】:

    首先,第一个版本更短且更具可读性。这在编程时总是一个很大的优势。

    至于性能,您应该始终首先进行分析,只有在发现瓶颈时才担心。但是在现代虚拟机上,它们最终可能会同样快(尽管同样,如果它很重要,您需要对其进行分析)。数组克隆通常通过内部函数实现,但 VM 可能会识别出第二个版本是等效的。

    【讨论】:

    • @alex23 OP提供的第二个版本是深拷贝,所以我猜他正在寻找深拷贝。
    猜你喜欢
    • 1970-01-01
    • 2012-07-17
    • 2011-03-16
    • 1970-01-01
    • 2016-09-20
    • 2021-04-10
    • 2011-04-24
    • 2018-01-29
    • 1970-01-01
    相关资源
    最近更新 更多