什么是PECS(生产者扩展消费者超级)?

2022-08-31 04:03:02

我在阅读泛型时遇到了PECS(生产者扩展和消费者超级的缩写)。

有人可以向我解释如何使用PECS来解决和之间的混淆吗?extendssuper


答案 1

tl;dr:“PECS”是从收藏的角度来看的。如果您只是从泛型集合中提取项目,则它是生产者,您应该使用 ;如果您只是将物品塞进去,则它是消费者,您应该使用.如果对同一集合执行这两项操作,则不应使用 或 。extendssuperextendssuper


假设您有一个方法,该方法将事物的集合作为其参数,但您希望它比仅接受 .Collection<Thing>

案例 1:您想浏览集合并对每个项目执行操作。
然后,该列表是生产者,因此您应该使用 .Collection<? extends Thing>

理由是 a 可以包含 的任何子类型,因此当您执行操作时,每个元素都将表现为 a。(您实际上无法向 添加任何内容(null 除外),因为您无法在运行时知道集合的哪个特定子类型包含。Collection<? extends Thing>ThingThingCollection<? extends Thing>Thing

案例 2:您要向集合中添加内容。
然后,该列表是使用者,因此应使用 .Collection<? super Thing>

这里的理由是,与 不同,无论实际的参数化类型是什么,它总是可以成立。在这里,您不在乎列表中已有的内容,只要它允许添加;这是保证。Collection<? extends Thing>Collection<? super Thing>ThingThing? super Thing


答案 2

在计算机科学中,这背后的原理被称为

  • 协方差:? extends MyClass
  • 逆方差:和? super MyClass
  • 不变性/非方差:MyClass

下图应该解释这个概念。图片提供:安德烈·秋金

Covariance vs Contravariance


推荐