我可以使用Arrays.copyOf来制作二维数组的防御副本吗?

时间:2013-04-12 04:27:35

标签: java

据我所知,我们可以使用java.util.Arrays.copyOf复制二维数组,但使用它进行防御性复制是否安全(假设元素是不可变的)? E.g。

void setValues(Integer[][] arr) {
    this.arr = Arrays.copyOf(arr, arr.length);
}

3 个答案:

答案 0 :(得分:1)

Arrays.copyOf在内部使用System.arraycopy,所以不,它不适合制作防御性(深层)副本(至少不适用于可变类型)。

答案 1 :(得分:1)

复制副本。

它复制指定的数组,截断或填充空值(如有必要),以便副本具有指定的长度。对于在原始数组和副本中都有效的所有索引,这两个数组将包含相同的值。

2771    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
2772        T[] copy = ((Object)newType == (Object)Object[].class)
2773            ? (T[]) new Object[newLength]
2774            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
2775        System.arraycopy(original, 0, copy, 0,
2776                         Math.min(original.length, newLength));
2777        return copy;
2778    }

Code reference - 打开jdk 6-b14

答案 2 :(得分:0)

不,它不是一本很深的副本。 arr看起来像这样(模拟内存地址):

@0x01 [
  @0x10 [1,2],
  @0x20 [2,3],
  @0x30 [4,5],
]

当您使用Arrays.copyOf制作副本时,您会获得一个新的外部数组,因此this.arr将是:

@0x02 [
  @0x10 [1,2],
  @0x20 [2,3],
  @0x30 [4,5],
]

如果你想确定你的2D阵列不会改变,你可以这样做:

this.arr = new Integer[arr.length][];
for (int i = 0; i < arr.length; i++) {
    this.arr[i] = Arrays.copyOf(arr[i], arr[i].length);
}

现在只是安全的,因为Integer是不可变的。如果它更复杂,您必须弄清楚如何安全地复制 ,这可能涉及更多副本。 Java并没有为您提供免费的深层拷贝。

相关问题