Struggling with understanding <? extends T> wildcard in Java
我有一个非常基本的问题。
下面的代码不编译(假设苹果扩展了水果):
1 2 | List<? extends Fruit> numbers = new ArrayList<>(); numbers.add(new Apple()); //compile time error |
当我读到"为什么"时,我理解的是单词,而不是概念。
假设第一个水果不是抽象类。我理解,因为我们处理的是多个子类型,所有这些子类型都扩展了水果。因为我们不能准确地说出水果的种类,所以我们不能把任何东西放进收藏品中。有几件事我不明白:
1)显然我们不知道是哪种水果让我困惑。在迭代集合时,我们是否能够通过typeof或其他instanceof check来分辨特定的类型?
2)假设水果是一个具体的类,为什么不允许我们添加水果实例?这似乎是有道理的,因为你至少知道水果的API。即使您不知道fruit的确切子类型,至少可以在fruit()上调用标准方法。
我觉得这应该是相当明显的,但有些东西不适合我。任何帮助都是感激。谢谢!
理解这一点的最好方法是将通配符视为对列表的某种说明,而不是水果。换句话说:
1 2 3 4 5 6 7 | List<Banana> allBananas = getMyBananas(); enumerateMyFruit(allBananas); static void enumerateMyFruit(List<? extends Fruit> myFruit) { for (Fruit fruit : myFruit) System.out.println(fruit); } |
当我们将
而且,您是对的,我们可以迭代列表并使用
你也可以看到为什么一个
还有一个是
首先要记住,对于没有通配符的泛型参数,不能用一个替换另一个。如果一个方法取一个
还请记住,
当一个方法foo接受一个泛型类型为
你可以通过一个
List 。你可以通过一个
List 。你可以通过一个
List 。
小精灵
(等,对于您拥有的
所以您的方法可以使用其中任何一个的列表,但是方法体必须对其中任何一个有效。当你把一个
这就是为什么有一个规则,即每当通配符类型扩展某个内容时,添加内容是不可能的,它无法适用于所有可以传入的可能类型。