问题描述
我不明白为什么会出现这些编译错误:
I cannot understand why I am getting these compilation errors:
1:
2:
static class Bird{}
static class Sparrow extends Bird{}
public static void main(String[] args){
List<? extends Bird> birds = new ArrayList<Bird>();
birds.add(new Sparrow()); //#1 DOES NOT COMPILE
birds.add(new Bird());// //#2 DOES NOT COMPILE
}
推荐答案
具有 List< ;?扩展了Bird>
,您实际上说的是 Bird子类型的任何类型 。这与说每种扩展 Bird
的类型不同。
With List<? extends Bird>
you actually say any type that is a subtype of Bird. It's not the same as saying every type that extends Bird
.
?
可以是 Sparrow
,但也可以是 Blackbird
。如果您尝试将麻雀
添加到可能仅包含 Blackbird
的列表中,它不会工作。出于相同的原因,您不能将 Bird
添加到可能是 Sparrow $ c $的列表的列表中c> s。
That means that ?
can be a Sparrow
, but it can also be a Blackbird
. If you try to add a Sparrow
to a list that could contain only Blackbird
s, it won't work. For that same reason you cannot add a Bird
to a list that could be a List of Sparrow
s.
为了使工作正常,您只需将列表的声明更改为:
In order to make things work, you just change the declaration of the list to this:
List<Bird> birds = new ArrayList<>();
或使用下限:
List<? super Bird> birds = new ArrayList<>();
关于这个下限示例:声明实际上说 Bird
或它的超类之一 。这意味着您可以安全地添加麻雀
或 Bird
,因为两者都符合这些条件。
About this lower bound example: the declaration actually says any type that is a Bird
or one of its superclasses. That means that you can safely add a Sparrow
or a Bird
, because both meet those criteria.
通常来说,您应该使用吗?超级...
,当您写入列表时,?从列表中读取时,扩展...
。如果您同时阅读和写作,则不应使用边界。
Generally speaking, you should use ? super ...
when you are writing to the list, and ? extends ...
when you are reading from the list. If you are both reading and writing, you shouldn't use bounds.
提供了有关泛型的非常有用的信息。
This answer provides very useful information about generics. You definitely should read it.
我认为以下陈述更加准确: 一个未知但特定的类型,它是 Bird
的子类型。
I think the following statement is even more accurate: "an unknown, but specific type that is a subtype of Bird
".
这篇关于上限通配符导致Java中的编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!