Nei*_*aft 33 java arrays clone
复制整个数组时,我经常看到人们写道:
int[] dest = new int[orig.length];
System.arraycopy(orig, 0, dest, 0, orig.length);
Run Code Online (Sandbox Code Playgroud)
但在我看来,没有理由支持这一点:
int[] dest = orig.clone();
Run Code Online (Sandbox Code Playgroud)
无论如何,它们都是浅色的.可能这些人只是没有意识到clone存在.那么有什么理由不使用clone?
小智 33
clone() 使用自己的引用制作第一个数组的不同副本.System.arraycopy()使用JNI(Java Native Interface)来复制一个数组(或部分数组),所以它非常快,你可以在这里确认
一下 ;clone()创建一个新的具有相同特征的老阵列,即,相同的大小,相同的类型,并且阵列相同的内容.请参阅此处了解一些实际操作示例clone;manual copying是,手动复制.没有太多的话要说,该方法相同,只是很多人都认为它是最高性能.arraynew = arrayold 不复制数组; 它只是指向 arraynew内存地址,arrayold或者换句话说,你只是指定一个旧数组的引用.使用System.arraycopyorArrays.copyOf代替clone()会使您的代码更明确,因此更容易理解。它说“我正在复制一个数组”,而不是“我正在(神奇地)复制某种对象”。
显式的比隐式的好。- Python 之禅
但支持这些Arrays.copyOf方法(和反对clone())的主要论据是类型安全,缺乏类型安全可能是最大的问题,clone()如果您不小心克隆的对象具有精确的类型,则可能会导致微妙的错误。您想要的数组组件类型。
让我们以JDK-6260652错误为例。罪魁祸首被clone()用来Arrays.ArrayList实现Collection.toArray()(声明为 return Object[])。这个特殊的类是通过用作其后备数组来实例化的ArrayList私有类,而不关心 的实际类型,它可能是or (或实际上不是的任何其他类型)。其方法在此处返回的问题是,程序员最终可能会在某个时候使用做这样的事情:java.util.ArraysArrays.asList(T... a)aaString[]Integer[]Object[]toArray()a.clone()Arrays.ArrayList.toArray()
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!
Run Code Online (Sandbox Code Playgroud)
这种错误可能会被忽视很多年,因为上面说明的使用模式并不常见。只要考虑一下集合框架自 JDK 1.2(1998 年)以来就已经存在,但这个特定问题直到 2005 年才被报告(10 年后有人在 JDK 的不同部分发现了类似的问题)。JDK-6260652(在 Java 9 中发布)的补丁只是a.clone()将Arrays.copyOf(a, a.length, Object[].class).
总而言之,我赞成使用数组复制方法的论点是clone():
System.arraycopy:
Arrays.copyOf:
当我在思考同样的疑问时,我偶然看到了这个问题.我觉得这arraycopy()是一个在预定义数组时使用的方法(即已经分配了内存).因此,不重复与存储器分配相关的开销.
例如,假设您定义了一个定期更新的大型数组.然后使用clone()将在每次复制数组时重新创建所需大小的数组.但是,arraycopy()使用预先分配的内存空间.
因此,arraycopy()在某些情况下,与之相比,效率更高clone().另一方面,clone()结果是紧凑的代码.
| 归档时间: |
|
| 查看次数: |
19206 次 |
| 最近记录: |