Upper-bound wildcard (extends) not working; ArrayList<? extends SuperType> doesn't allow instances of subtype
根据我对有界通配符的了解, extends Object>的类型参数将接受Object的所有子类型。正如Java教程所描述的:
The upper bounded wildcard, extends Foo>, where Foo is any type, matches Foo and any subtype of Foo
因此,如果我有扩展Position的GridPosition型,? extends Position应该接受GridPosition型。
问题
当试图将EDOCX1的实例(6)添加到用ArrayList extends Position>类型声明的列表中时,我得到一个错误:
The method add(capture#1-of ? extends Position) in the type ArrayList is not applicable for the arguments (GridPosition)
我所指的代码,以最简单的形式:
1 2 3 4 5 6 7 8 9 10 11
| import java.util.ArrayList;
public class Main {
public static void main (String[] args ) {
ArrayList <? extends Position > list = new ArrayList <>();
list. add(new GridPosition ()); // Error on this line
}
}
class Position {}
class GridPosition extends Position {} |
运行Java 8u31的Eclipse Luna中的错误图片:
这是虫子吗?或者我不理解有界通配符?
我注意到? super Position允许我将GridPosition的实例添加到列表中。
当使用带有 extends Position>类型参数的列表时,实例(来自下面的类)不起作用:
1 2 3
| class Super {}
class Position extends Super {}
class GridPosition extends Position {} |
图片:
- 对于这种情况,使用ArrayList并让duck输入处理它。这不是一个bug,但我不能正确解释为什么它不能工作。一些具有泛型的东西需要您指定一个类型以便对实例进行操作
- @费尔克,我不是在寻找答案,而不是解释未来的记录。我以前用过上界通配符,从来没有遇到过这个问题。本教程甚至指出它与Foo的子类型匹配。我不确定事情是否发生了变化,或者我是否理解了一些事情。Class extends Position> clazz = GridPosition.class工作正常
- @ VinceEmigh?List extends Position>是指Position的一些未知但特定亚型的列表。例如,它可以是一个List,添加一个GridPosition也是没有意义的。这就是List extends Position>的意思。
如果要添加到通用列表,则应使用super。extends用于读取(get等)操作。您可以在Joshua Bloch中找到有效Java的细节,项目28:使用有界通配符来增加API灵活性
- 我认为这更像是一个最佳实践(如:如何编写更好的API),但它并不能真正回答这个问题。不,我手头没有这本书。
- 你能详细说明一下什么是阅读操作吗?声明的类型如何在get操作中发挥作用?
- 从我提到的文章中:如果参数化类型表示t生产者,请使用<?扩展t>;如果它表示t消费者,则使用<?超级T>