Java 爪哇逆变疑问

Java 爪哇逆变疑问,java,generics,contravariance,Java,Generics,Contravariance,我读了这篇关于对冲的帖子: 现在让我们介绍另一个通配符:?超级。给定的超类型B 一种类型a,然后C是C的一个子类型,因为这就是逆变的工作原理水果消费者是苹果消费者的子类型,因为它也可以消费苹果,因此它支持为苹果消费者定义的操作(与协变生产者不同,即苹果生产者是水果生产者的子类型) 也就是说,当您的列表充当消费者时,您应该使用对冲,例如: public void fillWithApples(List<? super Apple> basket) { basket.add(ne

我读了这篇关于对冲的帖子:

现在让我们介绍另一个通配符:
?超级
。给定的超类型
B

一种类型
a
,然后
C
C的一个子类型,因为这就是逆变的工作原理水果消费者是苹果消费者的子类型,因为它也可以消费苹果,因此它支持为苹果消费者定义的操作(与协变生产者不同,即苹果生产者是水果生产者的子类型)

也就是说,当您的
列表
充当消费者时,您应该使用对冲,例如:

public void fillWithApples(List<? super Apple> basket) {
    basket.add(new Apple());
}

List<Apple> basketOfApples = ...;
fillWithApples(basketOfApples);

List<Fruit> basketOfFruits = ...;
fillWithApples(basketOfFruits);

List<Object> basketOfAnything = ...;
fillWithApples(basketOfAnything);

public void fillWithApples(List思考类型层次结构的一个有用规则是。基本上,它说A是B的一个子类型,意味着你可以在任何可以使用B的地方使用A。通常情况下,反之亦然

例如,假设我是一个邪恶的国王,他要求臣民以水果的形式向他进贡。你能给我举一个苹果的例子吗?是的,当然。苹果是水果的一种亚型。在山上,有人要求臣民以苹果的形式向他进贡。你能带来吗给他一根香蕉或其他水果?不!如果你这样做,他会让你被小马踩死的

所以,为了让你在我的王国里过上幸福长寿的生活,你需要一份水果。你可以把这份水果放在一份清单里。你可以把它放在一份清单里吗?是的,没问题。一份清单怎么样?好的,因为我会接受苹果公司的。所以为了生产的目的,
清单是可以的
List
的一个子类型。当然,在另一个邪恶国王的土地上,你只能拥有一个
List
,除非你想花很多时间将
List
的内容投射到
Apple
上,除非你是一个巫师,否则这很烦人

现在,每年的贡品日过后,我都会有一大堆水果。我甚至不喜欢水果,所以我不得不把它放在某个地方。最明显的地方是一个
列表
。我能在这里用一个
列表
吗?不!因为我亲爱的一些主题可能会给我带来香蕉,而我不能把它们放在这样的列表中。然而,我爱在山上,情况就不同了。那里的邪恶国王只对苹果感兴趣,所以他可以很高兴地用一个列表来储存他的营养贮藏。但是他能用一个列表来储存他的营养贮藏吗?是的!因为苹果是一种水果,所以他可以很容易地把它们放在这样一个列表中。这将是很容易的所以,为了消费的目的,我们看到可以使用
List
的人也可以使用
List
,所以我们有一个反常的情况,
List
List
的一个子类型。这就是为什么我不去另一个邪恶王国非常有趣的地方

尽管如此,它还是比Haskell Republic好。

按照规则“子类型的实例<代码>类子类型的实例应该是可分配的,在任何需要
类超类型的实例的地方,这是非常明显的


进一步扩展它-想象一个对
List
ListNice故事所做的操作…你可能想包括
ListOk,但我不明白为什么C是一个子类型而不是一个超类型!如果你可以从一个类型对对象做更多的事情,那么它更具体,它是一个子类型。很抱歉,写ListNo,
List
不在sub/sup中ertype与
列表的关系。只有通配符类型是非通配符类型的超类型。
C
public void fillWithApples(List<? super Apple> basket) {
    basket.add(new Apple());
}

List<Apple> basketOfApples = ...;
fillWithApples(basketOfApples);

List<Fruit> basketOfFruits = ...;
fillWithApples(basketOfFruits);

List<Object> basketOfAnything = ...;
fillWithApples(basketOfAnything);