.clone()或Arrays.copyOf()?

Bru*_*der 41 java immutability

为了减少可变性,我们应该使用

public void setValues(String[] newVals) {

     this.vals = ( newVals == null ? null : newVals.clone() );
}
Run Code Online (Sandbox Code Playgroud)

要么

public void setValues(String[] newVals) {

     this.vals = ( newVals == null ? null : Arrays.copyOf(newVals, newVals.length) );
}
Run Code Online (Sandbox Code Playgroud)

ass*_*ias 43

使用jmh更新

使用jmh,我得到了类似的结果,除了clone似乎稍微好一些.

原帖

我跑了性能快速测试:clone,System.arrayCopy并且Arrays.copyOf有非常相似的性能(JDK 06年7月1日,服务器VM).

有关详情(以毫秒为单位),在JIT之后:

clone:68
arrayCopy:68
Arrays.copyOf:68

测试代码:

public static void main(String[] args) throws InterruptedException,
        IOException {
    int sum = 0;
    int[] warmup = new int[1];
    warmup[0] = 1;
    for (int i = 0; i < 15000; i++) { // triggers JIT
        sum += copyClone(warmup);
        sum += copyArrayCopy(warmup);
        sum += copyCopyOf(warmup);
    }

    int count = 10_000_000;
    int[] array = new int[count];
    for (int i = 0; i < count; i++) {
        array[i] = i;
    }

    // additional warmup for main
    for (int i = 0; i < 10; i++) {
        sum += copyArrayCopy(array);
    }
    System.gc();
    // copyClone
    long start = System.nanoTime();
    for (int i = 0; i < 10; i++) {
        sum += copyClone(array);
    }
    long end = System.nanoTime();
    System.out.println("clone: " + (end - start) / 1000000);
    System.gc();
    // copyArrayCopy
    start = System.nanoTime();
    for (int i = 0; i < 10; i++) {
        sum += copyArrayCopy(array);
    }
    end = System.nanoTime();
    System.out.println("arrayCopy: " + (end - start) / 1000000);
    System.gc();
    // copyCopyOf
    start = System.nanoTime();
    for (int i = 0; i < 10; i++) {
        sum += copyCopyOf(array);
    }
    end = System.nanoTime();
    System.out.println("Arrays.copyOf: " + (end - start) / 1000000);
    // sum
    System.out.println(sum);
}

private static int copyClone(int[] array) {
    int[] copy = array.clone();
    return copy[copy.length - 1];
}

private static int copyArrayCopy(int[] array) {
    int[] copy = new int[array.length];
    System.arraycopy(array, 0, copy, 0, array.length);
    return copy[copy.length - 1];
}

private static int copyCopyOf(int[] array) {
    int[] copy = Arrays.copyOf(array, array.length);
    return copy[copy.length - 1];
}
Run Code Online (Sandbox Code Playgroud)

  • ...结论是`clone()`是最好的选择,是一个非常方法(没有参数搞砸了),它也像它可以得到的类型安全一样(感谢`clone()的返回类型协方差'对于数组类型). (16认同)
  • Arrays.copyOf在内部使用System.arrayCopy,因此无需在它们之间进行比较. (3认同)

Dal*_*rol 5

还请考虑使用“ clone()”的安全性。一类知名的攻击使用使用恶意代码覆盖对象的“ clone()”方法的类。例如,通过基本上将“ .clone()”调用替换为“ .copyOf”调用,解决了CVE-2012-0507(在Mac OS上为“闪回”攻击)。

关于“ clone()”过时性的其他讨论可以在这里的StackOverflow上找到:不执行可克隆接口而进行的对象克隆