java extends e,java泛型中的? extend E 和 ? super E

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());

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值