检查空集合的Java集合通用类型

我想实现以下function:

public boolean checkType(Vector vec) { // return true if its Vector and false otherwise } 

如何检查矢量元素类型? 请注意,向量可能为空,因此我无法检查第一个元素是“instanceof”Integer还是String …

编辑:

好吧,我有一些想法,我不知道它是否会起作用

我可以实现checkType函数,如下所示:

 public  boolean checkType(Vector vec) { // return true if T is Integer and false otherwise } 

是否有可能检查T是否为整数?

提前致谢

由于类型擦除, 通用类型参数在运行时是不可恢复的(除了一些特殊情况)。 这意味着在运行时, VectorVector都只是Vector ,它们的元素只是Object引用。

只有实际的运行时类(由你指出的instanceof检查可以发现)才能构成元素类型的概念,否则Vector本身不知道它的元素类型是什么。

所以基本上,任何类型的空向量等于任何其他类型的向量。 像这样投射它甚至是安全的:

 Vector noStrings = (Vector) new Vector(); 

但是有一个问题,因为虽然你可以说向量符合任何必需的元素类型,但只要向量保持为空 ,此语句就会起作用。 因为如果你这样做:

 Vector ints = new Vector(); // empty Vector strings = (Vector) ints; // unchecked warning, but still possibly ok ints.add(1); // here comes trouble String s = strings.get(1); // oh oh, ClassCastException 

编辑:

为了回答你的第二个问题:不可能写下这样的东西:

 public  boolean checkType(Vector vec) { return T instanceof Integer; // impossible return T == Integer; // impossible return T.class == Integer.class // impossible return vec instanceof (Vector); // impossible } 

但是,您可以编写一个使用类标记作为输入参数的方法:

 static  boolean checkElementType(Collection collection, Class 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 

任何告诉你这完全可能的人都是错的。 在运行时,无法判断空Vector是Vector还是Vector

这或多或少是类型擦除的定义

由于类型擦除,这是不可能的。

即使向量不为空,集合库也没有提供真正的保护,防止将不同类型的东西放入:

  Vector v = new Vector(); v.add("foo"); System.out.println(v.get(0)); 

将运行没有错误,并很好地打印不应该被允许的字符串值。

因此,即使通过检查第一个元素的类型,在运行时确定generics类型的任何尝试都是不可靠的。

您可以在自己的通用代码中执行的操作是添加构造函数参数和包含该值的字段,以便您的代码在运行时确实知道该类型。

这种策略很难应用于整个集合库,但是Vector一个开头就是:

 public class TypedVector extends Vector { private Class genericClass; public TypedVector(Class clazz) { super(); this.genericClass = clazz; } // many other constructors ... but probably not all of them public Class getGenericClass() { return genericClass; } @Override public boolean add(E e) { if (!(genericClass.isAssignableFrom(e.getClass()))) throw new IllegalArgumentException("Incorrect class"); return super.add(e); } // many other overrides for run-time type safety } 
 public boolean checkType(Vector vec) { if(!vec.isEmpty()) { if("String".equals(vec.get(0).getClass().getSimpleName())) return false; else if("Integer".equals(vec.get(0).getClass().getSimpleName())) return true; } } 

希望这可以帮助!!