假设我们有一个A类,它有两个子类A1,A2。 假设我们有另一个B类,它也有两个子类,B1和B2:
class B{
List<? extends A> myGenericList;
B(List<? extends A> myGenericList){
this.myGenericList = myGenericList;
}
public List<? extends A> getMyGenericList(){
return myGenericList;
}
}
class B1 extends B{
B1(List<A1> a1List){
super(a1List);
}
}
class B2 extends B{
B2(List<A2> a2List){
super(a2List);
}
}
现在,如果我们有这样的C1类:
class C1{
...
public void doSomethingWithB1(B1 b1){
List<A1> a1list = (List<A1>)b1.getMyGenericList();
}
...
}
如何实现B类的getMyGenericList,以避免未经检查的转换警告?
我试过这样的事情:
public <T extends A> List<T> getMyGenericList() {
return this.myGenericList;
}
但是编译器抱怨cannot convert from List<capture#3-of ? extends A> to List<T>
有什么办法吗?
提前致谢。
答案 0 :(得分:4)
使用您已定义B
类的当前方式,myGenericList
实例变量可以保存A的任何子类型的List,因此在转换为{时,您获得的未经检查的强制转换警告{1}}是合理的。它可以是List<A1>
或List<A>
。
如果您真的不在乎列表中的List<A2>
,则可以将其分配给A
。
List<? extends A>
但是如果你真的想从List<? extends A> a1list = b1.getMyGenericList();
获得List<A1>
,那么B1
课程中的泛型就是你的答案。在类级别定义B
,其上限为T
。在整个班级中使用它来替换您的通配符。
A
class B<T extends A>
{
List<T> myGenericList;
B(List<T> myGenericList){
this.myGenericList = myGenericList;
}
public List<T> getMyGenericList(){
return myGenericList;
}
}
的子类将分别定义B
。
T
这样你就可以消除未经检查的施法警告甚至根本不需要施放。
class B1 extends B<A1> // rest of class is the same
class B2 extends B<A2> // rest of class is the same
答案 1 :(得分:0)
您应该将通用定义移动到类级别,如下所示:
class B<T extends A> {
List<T> myGenericList;
B(List<T> myGenericList){
this.myGenericList = myGenericList;
}
public List<T> getMyGenericList(){
return myGenericList;
}
}
现在使用具体参数A1
:
class B1 extends B<A1>{
B1(List<A1> a1List){
super(a1List);
}
}