复制整个阵列时,我经常看到人们写道:
int[] dest = new int[orig.length];
System.arraycopy(orig, 0, dest, 0, orig.length);
但在我看来,没有理由赞成这个:
int[] dest = orig.clone();
无论如何,它们都是浅色的。可能这些人都没有意识到clone
存在。那么有什么理由不使用clone
?
答案 0 :(得分:31)
clone()
使用自己的引用制作第一个数组的不同副本。System.arraycopy()
使用JNI(Java Native Interface)进行复制
一个数组(或它的一部分),所以它是
你可以确认,非常快
here; clone()
创建一个 new 数组,其特征与旧数组相同,即相同大小,相同类型和相同内容。有关clone
正在运行的一些示例,请参阅here manual copying
是手动复制。关于这种方法没有太多可说的,只是很多人发现它是performant最多的。arraynew = arrayold
不复制数组;它只是指向 arraynew
到arrayold
的内存地址,换句话说,你只是将引用分配给旧数组。< / LI>
答案 1 :(得分:8)
否。如果您真的微基准测试,那么可能,取决于您正在运行的JVM。但实际上,没有。
答案 2 :(得分:5)
arraycopy()
是一个在预定义数组时使用的方法(即已经分配了内存)。因此,不会重复与内存分配相关的开销。
例如,假设您定义了一个定期更新的大型数组。然后使用clone()
将在每次复制数组时重新创建所需大小的数组。但是,arraycopy()
使用预先分配的内存空间。
因此arraycopy()
在某些情况下与clone()
相比效率更高。另一方面,clone()
会产生紧凑的代码。
答案 3 :(得分:1)
这里只是猜测,但可能有充分的理由使用System.arraycopy
,因为不同的JVM可以通过利用底层系统的本机能力来提高性能来实现它们。
例如,JVM实现可以使用像memcpy
这样的本机库调用,它可能会利用一些内存控制器技巧以一种非常快速和巧妙的方式执行操作。但是,由于其虚拟性,Object.clone
实现可能不适合进行此类优化。
答案 4 :(得分:1)
使用System.arraycopy
或Arrays.copyOf
而不是clone()
使您的代码更明确,因此更易于理解。它表示“我正在复制数组” ,而不是“我(魔术地)复制某种对象” 。
显式优于隐式。 -The Zen of Python
但是,支持Arrays.copyOf
方法(反对clone()
)的主要论点是 type-safety (类型安全性),缺少它可能是{{ 1}},如果您不小心要克隆的对象具有所需的确切数组组件类型,则可能导致细微的错误。
让我们看一下JDK-6260652错误。罪魁祸首是clone()
中使用clone()
来实现Arrays.ArrayList
(声明返回Collection.toArray()
)。这个特定的Object[]
是ArrayList
中的私有类,由java.util.Arrays
使用Arrays.asList(T... a)
作为其后备数组实例化,而无需关心a
的实际类型,是a
或String[]
(或其他实际上不是Integer[]
的东西)。其Object[]
方法在这里返回toArray()
的问题在于,程序员可能最终会在某个时候使用a.clone()
来执行以下操作:
Arrays.ArrayList.toArray()
这种错误可能会在很多年后被忽略,因为上面说明的使用模式并不常见。只需考虑Collections框架自JDK 1.2(1998年)以来就已经存在,但是直到2005年才报告此特定问题(十年后,有人在JDK的不同部分发现了similar issue)。 patch for JDK-6260652(在Java 9中发布)仅将List<String> lst = Arrays.asList("a", "b", "c");
// ... many lines of code later ...
Object[] arr = lst.toArray();
// ... at this point don't care about the original type of elements in lst ...
arr[0] = 123; // ArrayStoreException - WTF?!
// arr is an Object[] so should be able to store Integer values!
替换为a.clone()
。
总而言之,我赞成使用数组复制方法而不是Arrays.copyOf(a, a.length, Object[].class)
的观点是:
clone()
:
System.arraycopy
: