由于类型擦除,泛型类型参数在运行时是不可恢复的(某些特殊情况除外)。这意味着在运行时,两者Vector<Integer>
和Vector<String>
都只是Vector
s 并且它们的元素只是Object
引用。
只有单个元素的实际运行时类(instanceof
如您所指出的那样可以通过检查发现)构成元素类型的概念,否则 Vector 本身不知道它的元素类型是什么。
所以基本上,任何类型的空向量都等于任何其他类型的空向量。像这样投射它甚至是安全的:
Vector<String> noStrings = (Vector<String>) new Vector<Integers>();
但是有一个问题,因为尽管您可以说空向量符合任何所需的元素类型,但只要向量保持为空,此语句就成立。因为如果你这样做:
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