首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >泛型集合PECS

泛型集合PECS
EN

Stack Overflow用户
提问于 2013-02-13 22:45:04
回答 2查看 236关注 0票数 6

我有一个来自java.util.Collections的关于这个方法的问题

代码语言:javascript
复制
public class Collections {  
  public static <T> void copy(List<? super T> dest, List<? extends T> src) {  
      for (int i=0; i<src.size();i++)   
        dest.set(i,src.get(i));   
  }   
}

我理解<? super T>是如何工作的,但是我不明白为什么第一个参数是List<? super T>而不是List<T>。我认为在这种情况下它是无用的。

使用List<T>应该也可以,不是吗?

如果可能的话,你能给我举一些例子来理解它吗?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-13 22:51:46

不,这说得通。例如,考虑以下情况:

  • T is InputStream
  • dest is a List<Object>
  • src is a List<FileInputStream>

这绝对可以正常工作。当然,在这种情况下,您可以将T设置为ObjectFileInputStream -但想象一下,您是从具有以下签名的方法调用此方法:

代码语言:javascript
复制
public void doSomething(List<? super InputStream> streams) {
    // I want to use copy in here for some reason
}

你不知道它是一个List<InputStream> --只知道它是一个List<? super InputStream>。如果copy中的dest参数只是List<T>,我们就会被卡住……但按照它的编写方式,我们很好。

就我们对目的地列表的要求而言,这也是有意义的--我们只需要能够在其中设置T的值。同样,我们对源列表的所有要求就是可以从中获取T的值。<? super T><? extends T>很好地表达了这些需求。

票数 5
EN

Stack Overflow用户

发布于 2013-02-13 22:53:22

如果你将它分解为为什么使用这个列表,它将会更清晰一些。

当一个方法打算填充列表时,您可以将其限制为使用特定的类型T,但通常您可能希望限制较少。

例如,假设您有一个方法populateWithStudents(List<Student> list)Student extend Person

这意味着,即使List<Person>扩展了Person,也不能将该方法与学生对象一起使用来填充它。

因此,如果另一方面,我们希望允许将其更改为populateWithStudents(List<? super Student> list)。这样,我们就可以说,只要我们可以将一个Student放在列表中,无论它是一个Student对象的列表,还是它的任何超类的列表,它都是允许的。

显然,这不仅仅是填充时的情况,这个例子有助于理解这个概念。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14856109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档