个人对Java泛型中PECS原则的理解

在理解Java泛型中的PECS(Producer extends, consumer super)原则时查阅过很多博客,
其中我认为写的最容易理解的是《Java中的PECS》
另外一篇博客《你应该知道的泛型(Generic)与PECS原则》很形象,确不够全面
造成我有些地方困惑了好久。

PE原则

为什么在PE原则中可以读取内容?

我们都知道PE原则中使用的上界通配符("extends"),容器中存储的内容都有一个超级父类进行限制,里面的内容都只能是这个超级父类的子类。
所以从容器中读取的内容都可以被这个超级父类引用,因此PE原则中是可以读取内容的。

为什么在PE原则中不能添加内容?

这个问题困扰了我很久,在《你应该知道的泛型(Generic)与PECS原则》这篇博客中解释的原因是


编译器在这里遇到的问题是,如果add的是Apple类型时,则basket应该是List<Apple>,如果add是Fruit类型,则basket应该是List<Fruit>。而List<Apple>和List<Fruit>前面已经提过,是2个完全没有关系的类型, 所以编译器不知道是哪个子类型将加入集合,不知道到底是List<Apple>还是List<Fruit>,所以编译器只能报错。(注意,这里讨论的都是类型,而不是对象) 作者:马前小卒 链接:https://www.jianshu.com/p/e5b8cd33ec94 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

它给出的原因是“如果add的是Apple类型时,则basket应该是List\,如果add是Fruit类型,则basket应该是List\”,
当我看到这句话时当时的想法是就算"basket"类型不确定,我也可以继续向集合里面添加Apple,因为Fruit是Apple的父类,
但当我看到第二篇文章《Java中的PECS》时豁然开朗,
假设上面Fruit的子类还有一个Orange,那么Apple和Orange就是兄弟关系了,如果basket是List\,那么就不能向集合中添加Apple了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注