List<? extends MyType>
我有一个关于泛型的Java问题。我声明了一个通用列表:
1 | List<? extends MyType> listOfMyType; |
然后在某个方法中,我尝试实例化并向该列表添加项:
1 2 | listOfMyType = new ArrayList<MyType>(); listOfMyType.add(myTypeInstance); |
号
其中
The method add(capture#3-of ? extends
MyType) in the type Listis not applicable
for the arguments (MyType)
号
知道吗?
您不能对扩展执行"Put"。看看仿制药-获取和放置规则。
考虑:
1 2 3 4 5 6 7 | class MySubType extends MyType { } List<MySubType> subtypeList = new ArrayList<MySubType>(); List<? extends MyType> list = subtypeList; list.add(new MyType()); MySubType sub = subtypeList.get(0); |
号
在这种情况下,您不需要使用通配符捕获语法,只需声明
1 | List<MyType> listOfMytype; |
应该足够了。如果你想知道为什么,Java泛型教程比你想知道的关于Java泛型的深奥疯狂更为重要。第20页介绍了你的具体情况。
至于为什么用通配符捕获添加不起作用,这是因为编译器不能准确地确定MyType的子类,所以列表在每种情况下都是什么子类,所以编译器会发出一个错误。
这里有一个类似的线程:如何将元素添加到通配符泛型集合中?
要了解泛型的工作原理,请查看以下示例:
1 2 3 4 5 6 | List<SubFoo> sfoo = new ArrayList<SubFoo>(); List<Foo> foo; List<? extends Foo> tmp; tmp = sfoo; foo = (List<Foo>) tmp; |
问题是,它不是为局部/成员变量设计的,而是为函数签名设计的,这就是为什么它是如此向后的。
我不知道这是否真的对您有帮助,但这是我在调用Spring框架的通用方法并希望返回一个通用列表时必须使用的方法:
1 2 3 4 5 6 |
。
参数化似乎需要你使用?登录列表以接收结果,然后将列表强制转换为预期的返回类型。
我仍然被仿制药弄得眼花缭乱…