要求:
- 需要我的方法返回两个指定对象之一的列表。
- 需要将上述方法的结果存储为两个指定对象之一的列表。
声明了一个返回基于通配符的通用列表的方法。 声明部分正确,但方法调用失败。
class Z{/*TemplateClass*/}
public class A extends Z{}
public class B extends Z{}
测试类:
public List<? extends Z> getGenericList(boolean test){
if(test){
List<A> aList = new ArrayList<A>();
aList.add(new A());
return aList;
}
else{
List<B> bList = new ArrayList<B>();
bList.add(new B());
return bList;
}
}
这是我的要求。我需要类似下面的代码。
List<A> testAList = getGenericList(true);
List<B> testBList = getGenericList(false);
给我一个编译器错误。
Type mismatch: cannot convert from List< capture#1-of ? extends Z > to List< A > Type mismatch: cannot convert from List< capture#2-of ? extends Z > to List< B >
我明白这背后的逻辑。如果我们传递一个 false 并将返回的 B 列表存储为 A 列表会怎样,这是错误的。 但是当我使用下面的代码时:
List<? extends Z> testList = getGenericList(true);
它编译得很好。但这超出了我的目的。我无法访问 A 或 B 中的方法,因为 testList.get(index) 返回 Z 类型对象,我希望在其中获取 A 或 B。
如果我的代码绝对错误,那么任何正确方向的指针将不胜感激。
最佳答案
您可以对结果进行强制转换,这将使编译器错误消失,但您会得到一个不安全的强制转换,这看起来像是代码味道:
List<A> testAList = (List<A>) getGenericList(true);
List<B> testBList = (List<B>)getGenericList(false);
此外,如果 boolean 输入不是严格要求,您也可以执行以下操作:
public <T extends Z> List<T> getGenericList(Class<T> klass) {
List<T> list = new ArrayList<T>();
try {
list.add(klass.newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return list;
}
关于java - 使用通配符返回通用类型对象的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22367870/