在 java 中使用带嵌套泛型的通配符
Using wildcards with nested generics in java
我有一个 class 列表,它可以同时采用通用 Number
和 Double
来执行特定计算。
这很好用:
public class Test<T extends Number> {
public void testGeneric(List<T> list){
doTest(list);
}
public void testExplicit(List<Double> list){
doTest(list);
}
public void doTest(List<? extends Number> testList){}
}
但是,如果所讨论的参数是嵌套类型,则它不再编译:
public class Test<T extends Number> {
public void testGeneric(List<List<T>> list){
doTest(list);
}
public void testExplicit(List<List<Double>> list){
doTest(list);
}
public void doTest(List<List<? extends Number>> testList){}
}
请注意,列表的功能并不重要,第二个列表类型可以是任何通用类型,例如 T 类型的包装器。我真的不明白为什么会有任何区别。有解决办法吗?
谢谢!
您显然已经意识到,List<Double>
不是 List<Number>
的子类型;您需要通配符才能将 "propagate" 继承到泛型类型中:List<Double>
是 List<? extends Number>
的子类型。但是,通配符必须从最外层开始:只有当 X
恰好 时,List<X>
才是 List<List<? extends Number>>
的子类型 List<? extends Number>
。如果要接受List<? extends Number>
的其他子类型,比如List<Double>
,则需要List<? extends List<? extends Number>>
.
我有一个 class 列表,它可以同时采用通用 Number
和 Double
来执行特定计算。
这很好用:
public class Test<T extends Number> {
public void testGeneric(List<T> list){
doTest(list);
}
public void testExplicit(List<Double> list){
doTest(list);
}
public void doTest(List<? extends Number> testList){}
}
但是,如果所讨论的参数是嵌套类型,则它不再编译:
public class Test<T extends Number> {
public void testGeneric(List<List<T>> list){
doTest(list);
}
public void testExplicit(List<List<Double>> list){
doTest(list);
}
public void doTest(List<List<? extends Number>> testList){}
}
请注意,列表的功能并不重要,第二个列表类型可以是任何通用类型,例如 T 类型的包装器。我真的不明白为什么会有任何区别。有解决办法吗?
谢谢!
您显然已经意识到,List<Double>
不是 List<Number>
的子类型;您需要通配符才能将 "propagate" 继承到泛型类型中:List<Double>
是 List<? extends Number>
的子类型。但是,通配符必须从最外层开始:只有当 X
恰好 时,List<X>
才是 List<List<? extends Number>>
的子类型 List<? extends Number>
。如果要接受List<? extends Number>
的其他子类型,比如List<Double>
,则需要List<? extends List<? extends Number>>
.