0

据我了解,我们可以java.util.Arrays.copyOf用来复制二维数组,但是将它用于防御性复制是否安全(假设元素是不可变的)?例如

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

3 回答 3

1

不,这不是深拷贝。 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],
]

如果你想确保你的二维数组不会改变,你可以这样做:

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 不为您提供免费的深拷贝。

于 2013-04-12T04:36:44.543 回答
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    }

代码参考——打开jdk 6-b14

于 2013-04-12T04:37:52.743 回答
1

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

于 2013-04-12T04:33:26.767 回答