2

我想实现以下功能:

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

如何检查矢量元素类型? 请注意,向量可能为空,因此我无法检查第一个元素是“instanceof”整数还是字符串...

编辑:

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

我可以按如下方式实现 checkType 函数:

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

是否可以检查 T 是否为整数?

提前致谢

4

4 回答 4

4

由于类型擦除,泛型类型参数在运行时是不可恢复的(某些特殊情况除外)。这意味着在运行时,两者Vector<Integer>Vector<String>都只是Vectors 并且它们的元素只是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
于 2012-09-08T12:47:55.587 回答
2

任何告诉你这是可能的人都是错误的。在运行时,无法判断空 Vector 是 aVector<Integer>还是Vector<Rainbow>

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

于 2012-09-08T12:39:30.633 回答
2

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

即使向量不为空,集合库也不能真正防止将不同类型的东西放入:

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

将毫无错误地运行并很好地打印不应被允许的字符串值。

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

您可以在自己的通用代码中做的是添加一个构造函数参数和一个保存该值的字段,以便您的代码运行时知道类型。

这种策略很难应用于整个馆藏库,但首先Vector是:

public class TypedVector<E> extends Vector<E> {

    private Class<E> genericClass;

    public TypedVector(Class<E> 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
}
于 2012-09-08T13:25:56.100 回答
-2
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;               
   }
}

希望这可以帮助!!

于 2012-09-08T12:14:25.553 回答