努力理解Java中的通配符

努力理解Java中的通配符,第1张

努力理解Java中的通配符

理解这一点的最好方法是将通配符认为是关于列表的某件事,而不是水果。换一种说法:

List<Banana> allBananas = getMyBananas();enumerateMyFruit(allBananas);static void enumerateMyFruit(List<? extends Fruit> myFruit) {    for (Fruit fruit : myFruit)        System.out.println(fruit);}

当我们传递

allBananas
给时
enumerateMyFruit
,在方法内部,我们将丢失有关列表的原始声明类型的信息。在这个例子中,我们可以很清楚地看到为什么我们不能把苹果放在例如中
List<?extends Fruit>
,因为我们知道列表实际上是一个
List<Banana>
。再次,通配符告诉我们有关列表的声明类型的信息。

List<? extendsFruit>
应该读为“最初声明要保留的列表
Fruit
或的子类型
Fruit
,但我们不知道该声明类型是什么”。我们所知道的是,我们从列表中拉出的所有内容都是一个
Fruit

另外,您是对的,我们可以迭代列表并使用它

instanceof
来查找列表中实际包含的内容,但这并不能告诉我们列表的原始声明类型。在上面的代码片段中,我们发现列表中的所有内容都是a
Banana
,但是我可以很容易地将其声明
allBananas
为a
List<Fruit>


您可能还会看到为什么a

List<Dog>
不是a
List<Animal>

的原因。通配符是我们如何在泛型类型之间进行协方差。a
List<Dog>
不是a,
List<Animal>
而是a
List<? extends Animal>
。这带有我们不能添加到的限制
List<?extends Animal>
,因为它可能是
List<Dog>
,a
List<Cat>
或其他。我们不知道了。

另外还有

?super
,这是相反的。我们可以将其存储
Fruit
在中,
List<?super Fruit>
但我们不知道要从中取出哪种对象。它的原始声明类型实际上可能是例如
List<Object>
,其中包含各种其他内容。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5487055.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存