例如,我有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检查。请使用其擦除对象,因为在运行时将删除其他泛型类型信息
但是我没有得到确切的问题,在编译时所有可能的返回类型都是已知的?
答案 0 :(得分:5)
但是我没有得到确切的问题,在运行时所有可能的返回类型都是已知的?
不,由于类型擦除,在运行时T
的类型不已知。编译器无法对强制转换或instanceof
运算符执行任何有用的操作。
但是,由于您已经有参数Class<T> resultClass
,因此可以使用:
if (resultClass.isInstanceOf(o))) {
ret.add(resultClass.cast(o));
}
有关类型擦除(以及一般泛型)的更多信息,请参阅Java generics FAQ。
答案 1 :(得分: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;
}
答案 2 :(得分:1)
由于您拥有预期结果的Class,因此您可以执行以下操作:
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 ... < / p>