为什么List <! - ?扩展Foo - >不接受Foo类的对象?

时间:2018-04-08 20:38:53

标签: java

我尝试将类Foo的对象添加到List<? extends Foo>,但代码无法编译。

final Foo[] array = new Foo[] {new Foo()};
final List<? extends Foo> list = new ArrayList<>(array.length);
for (final Foo foo : array)
{
     // The List<? extends Foo> does not accept the foo object.
     list.add(foo);
}

这是个问题:为什么会这样?这没有任何意义,是吗?我只想要一个List,它可以包含扩展Foo类的对象。

1 个答案:

答案 0 :(得分:4)

我认为你误解了List<? extends Event>实际意味着什么。它并不意味着“我可以将Event的任何子类添加到此列表中”。这只是List<Event>的内容,因为子类可以上传到EventList<? extends Event>说“有一些Event的子类限制了这种类型”。因此,如果foo的类型为List<? extends Event>,则foo可能是List<Event>,但它也可能是List<SomeSpecificTypeOfEvent>,在这种情况下,您不是SomeSpecificTypeOfEvent允许添加 List<Event>的内容。我想你想要的只是extends;通配符在这里是过度的,没有必要。

进一步阅读方差注释(superList<Event>):https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

编辑:正如Johannes Kuhn在评论中指出的那样,如果你所做的只是在列表中添加元素,那么你可以拥有的最常规类型不是List<? super Event>但是Event,因为您可以切实地传递任何超类型? super Event的列表,并且您的方法仍然可以正常工作。必须要小心,因为使用string output = BitConverter.ToString(result).Replace("-", ""); 可能导致稍后尝试访问列表元素的某些问题,但如果您在该方法中所做的只是写入列表,那么它的工作原理完美。