本文共 1436 字,大约阅读时间需要 4 分钟。
public class TestType {
public static void main(String[] args) {
//? extend A,指的是A及A的子类
List extends A> list = new ArrayList();
//list.add(new A());//错误,编译不通过
//list.add(new B());//错误,编译不通过
list.add(null);
//? super B,只能接受B或B的子类
List super B> list1 = new ArrayList();
list1.add(new C()); //编译通过
//list1.add(new A()); //错误,编译不通过
}
}
class A{
}
class B extends A{
}
class C extends B{
}
? extend E : 指的是E及其E的子类,指定了泛型的上限(E),由于E是该范围内最上面的类,所以在list.add(具体类)是不可以的,因为只知道泛型的上限,但具体添加的对象和 list = new ArrayList<>(),中的类不一定匹配,会出现类型转换问题,所以干脆不可以添加。
? super E : 指的是E及其E的父类,指定了泛型的下限(E),由于指定了泛型的下限E,所以添加的对象只能是E或者E的子类,这样就不会出现类型转换错误,这就可以添加了,编译成功。从上面的示例中,我们看出,? extend E,不能添加元素,只能添加无意义的null。我们想要添加元素,该怎做办呢?可以使用 super E>。
那么这里,我们可以总结一条规律,“Producer Extends,Consumer Super”,意思是:
Producer Extends:如果你需要一个只读的List,用它来produce T,那么使用 ? extends T
Consumer Super:如果你需要一个只写的List,用它来consumer T,那么使用 ? super T
如果需要同时读取和写入,那么就不能使用通配符了。
Java集合类的源码中,经常有将两者结合起来使用的,如:
public class Collections{
public static void copy(List super T> dest, List extends T> src) {
int srcSize = src.size();
if (srcSize > dest.size())
throw new IndexOutOfBoundsException("Source does not fit in dest");
if (srcSize < COPY_THRESHOLD ||
(src instanceof RandomAccess && dest instanceof RandomAccess)) {
for (int i=0; i
dest.set(i, src.get(i));
} else {
ListIterator super T> di=dest.listIterator();
ListIterator extends T> si=src.listIterator();
for (int i=0; i
di.next();
di.set(si.next());
}
}
}
}
转载地址:https://blog.csdn.net/weixin_32541663/article/details/115593873 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!