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[]>
(其中 T
是 Animal
), 我们必须施放它。
说你要处理array covariance。你仍然有一个 Dog[]
和一个 Animal[]
,除了现在你的 Animal[]
实际上可能是 Subclass[]
对于 [=] 的任何子 class Subclass
21=]。你想将你的 Dog[]
复制到你的 Subclass[]
的任何类型的数组中(也许你的 class 层次结构在 Dog
和 Animal
之间,我不知道).那还是
Animal[] copy = Arrays.copyOf(dogArray, dogArray.length, animalArray.getClass());
但现在 animalArray.getClass()
确实不是 Class<Animal[]>
,执行强制转换是完全错误的。让 copyOf
服用 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[]>
(其中 T
是 Animal
), 我们必须施放它。
说你要处理array covariance。你仍然有一个 Dog[]
和一个 Animal[]
,除了现在你的 Animal[]
实际上可能是 Subclass[]
对于 [=] 的任何子 class Subclass
21=]。你想将你的 Dog[]
复制到你的 Subclass[]
的任何类型的数组中(也许你的 class 层次结构在 Dog
和 Animal
之间,我不知道).那还是
Animal[] copy = Arrays.copyOf(dogArray, dogArray.length, animalArray.getClass());
但现在 animalArray.getClass()
确实不是 Class<Animal[]>
,执行强制转换是完全错误的。让 copyOf
服用 Class<? extends T[]>
会更安全。