1

例如,我有 A、B、C 类,它们都在一个中List<Object>(列表来自 XML-Parser,我对这部分没有影响)。通常我只需要一种类型。所以我写了以下课程:

public class FilterForObject{
public static List<A> extractA(Result r){
  return extractClass(r,A.class);
}
public static List<B> extractB(Result r){
  return  extractClass(r,B.class);
}
public static List<C> extractC(Result r){
  return  extractClass(r,C.class);
}

private static <T> List<T> exctracClass(final Result r,final Class<T> resultClass) {
    List<T> ret = new ArrayList<T>(40);
    for (Object o : r.getAorBorC()) {
        if( o instanceof T){
            ret.add((T)o); // For some reasons this doesn't work
        }
    }
    return ret;
}

}

我遇到了以下警告:

无法对类型参数 T 执行 instanceof 检查。请改用其擦除对象,因为更多的泛型类型信息将在运行时被擦除

但我没有得到确切的问题,在编译时所有可能的返回类型都是已知的?

4

3 回答 3

5

但我没有得到确切的问题,在运行时所有可能的返回类型都是已知的?

不,在运行时类型T未知的,因为类型擦除。编译器不能对强制转换或instanceof运算符做任何有用的事情。

但是,由于您已经有了一个Class<T> resultClass可以使用的参数:

if (resultClass.isInstanceOf(o))) {
    ret.add(resultClass.cast(o));
}

有关类型擦除(以及一般泛型)的更多信息,请参阅Java 泛型常见问题解答

于 2013-03-07T13:50:26.857 回答
3

您已经为泛型类型参数传递了类型标记,您可以(并且必须)使用它而不是编译器生成的强制转换:

private static <T> List<T> exctracClass(final Result r,final Class<T> resultClass) {
    List<T> ret = new ArrayList<T>(40);
    for (Object o : r.getAorBorC()) {
        if(resultClass.isInstance(o)){
            ret.add(resultClass.cast(o));
        }
    }
    return ret;
}
于 2013-03-07T13:51:00.490 回答
1

由于您有预期结果的类,您可以执行以下操作:

private static <T> List<T> extractClass(final Result r, final Class<T> resultClass) {
    List<T> ret = new ArrayList<T>(40);
    for (Object o : r.getAorBorC()) {
        if (resultClass.isInstance(o)) {
            ret.add((T) o); // For some reasons this doesn't work
        }
    }
    return ret;
}

您可以对某些特殊构造(instanceof、casting...)支持的类和实例执行的所有操作,也可以通过 Class 对象上的方法执行:isInstance、cast、asSubclass...

于 2013-03-07T13:55:33.260 回答