java.util.Arrays.copyOf(U[], int, Class<? extends T[]>) 中通用通配符的优势

Advantage of generic wildcard in java.util.Arrays.copyOf(U[], int, Class<? extends T[]>)

我一直在浏览 java 本机源代码,发现在 java.util.Arrays.copyOf(U[], int, <code>Class<? extends T[]>) 中明显使用了通用通配符:

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
    @SuppressWarnings("unchecked")
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}

我想知道通用通配符 <code>Class<? extends T[]> 的优势是什么,而不仅仅是 <code>Class<T[]>,参数 newType,因为 T 本身并没有在其他任何地方更明确地声明。
实际上,我更愿意看到一个被详细质疑的潜在劣势here

与允许这样做的原因相同:

Object[] o = new Integer[1];

我猜,应该是back-compatible/consistent。

如果我尝试将该 o 数组中的一个位置设置为字符串怎么办?出现 运行 次异常:S

这就是裸数组有些损坏的原因,您应该尝试只将它们用于私有字段,否则您最好只使用 List<E> 之类的集合。

假设您有一个 Dog[] 和一个 Animal[],并且您想将 Dog[] 复制到 Animal[]:

Dog[] dogArray = whatever;
Animal[] animalArray = whatever;
Animal[] copy = Arrays.copyOf(dogArray, dogArray.length, animalArray.getClass());

animalArray.getClass() returns a Class<? extends Animal[]>,所以如果方法采用 Class<T[]> 而不是 Class<? extends T[]>(其中 TAnimal), 我们必须施放它。


说你要处理array covariance。你仍然有一个 Dog[] 和一个 Animal[],除了现在你的 Animal[] 实际上可能是 Subclass[] 对于 [=] 的任何子 class Subclass 21=]。你想将你的 Dog[] 复制到你的 Subclass[] 的任何类型的数组中(也许你的 class 层次结构在 DogAnimal 之间,我不知道).那还是

Animal[] copy = Arrays.copyOf(dogArray, dogArray.length, animalArray.getClass());

但现在 animalArray.getClass() 确实不是 Class<Animal[]>,执行强制转换是完全错误的。让 copyOf 服用 Class<? extends T[]> 会更安全。