为什么这个问题不是How Arrays.asList(int[]) can return List<int[]>?的可能重复。
这个问题并不能真正回答我的特殊情况,因为我试图弄清楚我对Arrays.copyOf的使用是否存在差异。

案例1:假定的阵列深拷贝

    // Creating a integer array, populating its values
    int[] src = new int[2];
    src[0] = 2;
    src[1] = 3;
    // Create a copy of the array
    int [] dst= Arrays.copyOf(src,src.length);
    Assert.assertArrayEquals(src, dst);
    // Now change one element in the original
    dst[0] = 4;
    // Following line throws an exception, (which is expected) if the copy is a deep one
    Assert.assertArrayEquals(src, dst);


情况2:
这是看起来很奇怪的地方:
我正在尝试使用以下方法(从书中逐字逐字逐句地进行)创建输入数组参数副本的不可变列表视图。这样,如果输入数组更改,则返回列表的内容不会更改。

    @SafeVarargs
    public static <T> List<T> list(T... t) {
    return Collections.unmodifiableList(new ArrayList<>(Arrays.asList(Arrays.copyOf(t, t.length))));
}


 int[] arr2 = new int[2];
    arr2[0] = 2;
    arr2[1] = 3;
    // Create an unmodifiable list
    List<int[]> list2 = list(arr2);

    list2.stream().forEach(s -> System.out.println(Arrays.toString(s)));
    // Prints [2, 3] as expected

    arr2[0] = 3;

    list2.stream().forEach(s -> System.out.println(Arrays.toString(s)));
    // Prints [3, 3] which doesn't make sense to me... I would have thought it would print [2, 3] and not be affected by my changing the value of the element.


我看到的矛盾是,在一种情况下(案例1),Arrays.copyOf似乎是一个深层副本,而在另一种情况下(案例2),它似乎是一个浅层副本。即使在创建无法修改的列表时复制了该数组,对原始数组的更改似乎也已写入列表。

有人可以帮助我解决这一差异吗?

最佳答案

首先,您的list方法执行不必要的步骤,您不需要copyOf操作,因此请执行以下操作:

@SafeVarargs
public static <T> List<T> list(T... t) {
    return Collections.unmodifiableList(
        new ArrayList<>(Arrays.asList(t))
    );
}


ArrayList构造函数已经复制了传入列表,因此您很安全。

接下来,当您使用int []调用list()方法时,该数组被视为int []类型的单个元素,因为T ...的类型擦除是Object ...,而int是原始的。在不更改参数类型或不执行instanceOf检查并在方法内部手动执行复制的情况下,无法使您的方法在列表内进行深层复制。我想说的最明智的事情可能是将Arrays.copyOf()调用移到方法之外:

List<int[]> list2 = list(Arrays.copyOf(arr2));

10-04 13:49