我一直在浏览java原生资源,并在java.util.Arrays.copyOf(U[], int,
中明显使用了通用通配符:Class<? extends T[]>
)
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;
}
的通用通配符
而不仅仅是Class<? extends T[]>
Class<? extends T[]>
的优势是什么,因为
本身并未在其他地方更明确地声明反正。Class<T[]>
实际上,我更倾向于看到一个潜在的劣势,这个缺点被详细询问here。
答案 0 :(得分:0)
假设您有Dog[]
和Animal[]
,并且想要将Dog[]
复制到Animal[]
:
Dog[] dogArray = whatever;
Animal[] animalArray = whatever;
Animal[] copy = Arrays.copyOf(dogArray, dogArray.length, animalArray.getClass());
animalArray.getClass()
会返回Class<? extends Animal[]>
,因此如果该方法采用Class<T[]>
代替Class<? extends T[]>
(其中T
为Animal
),我们不得不施展它。
说你必须处理array covariance。您仍然有一个Dog[]
和一个Animal[]
,但现在Animal[]
可能实际上是Subclass[]
Subclass
的任何子类Animal
。你想将你的Dog[]
复制到Subclass[]
真正属于的任何类型的数组中(也许你的班级中有一些东西在Dog
和Animal
之间层层叠叠,我不知道。那仍然是
Animal[] copy = Arrays.copyOf(dogArray, dogArray.length, animalArray.getClass());
但现在animalArray.getClass()
确实不是Class<Animal[]>
,执行演员会是完全错误的。让copyOf
获得Class<? extends T[]>
会更加安全。
答案 1 :(得分:-1)
这是允许这样做的原因相同:
Object[] o = new Integer[1];
我想,这只是反向兼容/一致。
如果我尝试将o
数组中的一个位置设置为String,该怎么办?发生运行时异常:S
这就是为什么裸阵列有点破碎,你应该尝试只将它们用于私人领域,否则你最好只使用像List<E>
这样的集合。