5

我正在阅读的一本关于 Java 的书告诉我,以下两段代码是等价的:

public <T extends Animal> void takeThing(ArrayList<T> list)

public void takeThing(ArrayList<? extends Animal> list);

在相反的页面上,我被告知后一段代码使用了“?” 作为通配符,意味着不能将任何内容添加到列表中。

这是否意味着如果我有一个列表(或其他集合类型?)我不能让它们同时接受多态参数并且可以重新调整大小?还是我只是误解了什么?

所有帮助/评论都表示赞赏,即使它们稍微偏离主题。谢谢。

4

2 回答 2

2

这是否意味着如果我有一个列表(或其他集合类型?)我不能让它们同时接受多态参数并且可以重新调整大小?

不。

两段代码并不完全等价。在第一行,该方法takeThing有一个类型参数T。在第二行中,您使用的是通配符。

当您使用第一个版本时,您将指定要使用的具体类型T。因为具体类型是已知的,所以添加到列表中没有问题。

在第二个版本中,您只是说“list是一个ArrayList包含扩展的某些未知类型的对象Animal”。这种类型究竟是什么,尚不得而知。您不能将对象添加到这样的列表中,因为编译器没有足够的信息(它不知道实际类型是什么)来检查您添加到列表中的内容是否应该被允许。

于 2012-11-20T14:02:32.080 回答
1

通常,如果添加到列表涉及到一个只接受列表而不接受要添加的东西的方法,那么您将在其他地方拥有一些东西,Animal并且您会想要将其添加到列表中。在这种情况下,必须声明您的方法,以便它接受的所有列表类型都允许Animal在其中添加一个。这必须是某个超类型的一个List<Animal>或一个列表。它不可能是 a — 您添加的元素可能是 any 。AnimalList<Dog>Animal

This is where the concept of the lower bound, and the keyword super, come in. The type declaration List<? super Animal> matches all the acceptable types as described above. On the other hand, you won't be able to get elements out of such a list in a typesafe way because they can in general be of any type at all. If a method wants to both add and get elements of declared type Animal, the only valid type it can accept is a List<Animal>.

于 2012-11-20T17:01:05.457 回答