我有一个来自java.util.Collections的关于这个方法的问题
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>应该也可以,不是吗?
如果可能的话,你能给我举一些例子来理解它吗?
谢谢。
发布于 2013-02-13 22:51:46
不,这说得通。例如,考虑以下情况:
T is InputStreamdest is a List<Object>src is a List<FileInputStream>这绝对可以正常工作。当然,在这种情况下,您可以将T设置为Object或FileInputStream -但想象一下,您是从具有以下签名的方法调用此方法:
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>很好地表达了这些需求。
发布于 2013-02-13 22:53:22
如果你将它分解为为什么使用这个列表,它将会更清晰一些。
当一个方法打算填充列表时,您可以将其限制为使用特定的类型T,但通常您可能希望限制较少。
例如,假设您有一个方法populateWithStudents(List<Student> list)和Student extend Person
这意味着,即使List<Person>扩展了Person,也不能将该方法与学生对象一起使用来填充它。
因此,如果另一方面,我们希望允许将其更改为populateWithStudents(List<? super Student> list)。这样,我们就可以说,只要我们可以将一个Student放在列表中,无论它是一个Student对象的列表,还是它的任何超类的列表,它都是允许的。
显然,这不仅仅是填充时的情况,这个例子有助于理解这个概念。
https://stackoverflow.com/questions/14856109
复制相似问题