泛型类型参数由于type erasure而在运行时不可恢复(某些特殊情况除外)。这意味着在运行时,Vector<Integer> 和 Vector<String> 都只是 Vectors,它们的元素只是 Object 引用。
只有各个元素的实际运行时类(如您所指出的那样,可以通过 instanceof 检查发现)才构成元素类型的概念,否则 Vector 本身不知道它的元素类型是什么。
所以基本上,任何类型的空向量都等于任何其他类型的 empty 向量。像这样投射它甚至是安全的:
Vector<String> noStrings = (Vector<String>) new Vector<Integers>();
但是有一个问题,因为虽然你可以说 empty 向量符合任何所需的元素类型,但这个说法只有只要向量保持为空。因为如果你这样做:
Vector<Integer> ints = new Vector<Integer>(); // empty
Vector<String> strings = (Vector<String>) ints; // unchecked warning, but still possibly ok
ints.add(1); // here comes trouble
String s = strings.get(1); // oh oh, ClassCastException
编辑:
回答你第二个问题:不,不可能这样写:
public <T> boolean checkType(Vector<T> vec) {
return T instanceof Integer; // impossible
return T == Integer; // impossible
return T.class == Integer.class // impossible
return vec instanceof (Vector<Integer>); // impossible
}
但是您可以编写一个使用类标记作为输入参数的方法:
static <T> boolean checkElementType(Collection<?> collection, Class<T> elementType) {
for (Object object : collection) {
if (!elementType.isAssignableFrom(object.getClass())) {
return false;
}
}
return true;
}
然后你可以像这样使用它:
List<?> list1 = Arrays.asList(1, 2, 3);
List<?> list2 = Arrays.asList(1, 2, 3, "a");
System.out.println(checkElementType(list1, Integer.class)); // true
System.out.println(checkElementType(list2, Integer.class)); // false