java 泛型上下限的例子

public static void doGenericExtends(List<? extends Goods> list) {
Goods goods = new Goods();
GoodsChild goodsChild = new GoodsChild();
GoodsParent goodsParent = new GoodsParent();
// list.add(goods); compile error
// list.add(goodsChild); compile error
// list.add(goodsParent); compile error
Goods g1 = list.get(0);
// GoodsChild gc = list.get(0); compile error
GoodsParent gp = list.get(0);
Object o = list.get(0);
}
public static void doGenericSuper(List<? super Goods> list) {
Goods goods = new Goods();
GoodsChild goodsChild = new GoodsChild();
GoodsParent goodsParent = new GoodsParent();
list.add(goods);
list.add(goodsChild);
// list.add(goodsParent); compile error
// Goods g1 = list.get(0); compile error
// GoodsChild gc = list.get(0); compile error
// GoodsParent gp = list.get(0); compile error
Object o = list.get(0);

}

写了两个方法,这两个方法用到三个实体 GoodsParent,Goods,GoodsChild,从左往右依次是爷爷,爹,儿子的关系

把代码的注释去掉后,都会报编译错误,下面从插入list、取list里面的数据两个角度,说一下自己的理解

首先,在doGenericExtends中,传入的参数类型,一定要是goods,或者是goods的子类,为什么三种类型的实例都不能添加到list中呢,因为:实际调用这个方法的时候,传入的?可能是任何的Goods或者Goods的子类,注意,就是这里,既然能传入任意的goods的子类,比如goodsChild,这样的话是肯定不能add Gooods类型的实例的。由于具体传入参数类型的不确定性,所以添加这几种类型都是不可以的。

再看从list中获取数据,因为Goods是上限,所以,编译器认为,无论传入什么类型,它都是Goods或者Goods的子类,

注意,这里就是最绕的地方:添加的时候,不知道传进来什么类型,但是获取的时候,由于extends 限定,所以获取数据的时候知道什么类型,是不是很恶心


然后,再看doGenericSuper,由于Goods是下限,所以实际使用的时候传进来的类型肯定≥Goods,所以add  goods也好,goodsChild也好,都是允许的,因为goods和goodsChild一定是传进来的某种类型的子类,所以是通过的,但是add goodsParent就不行,因为不能确定实际传入的类型比goodsParent要低。

获取的时候就麻烦了,因为不知道上限具体是什么类型,所以除了指定Object,其他类型都是报错的。

over

java泛型就是这部分最难理解了,由于我工作当中的场景,一直是写业务逻辑比较多,涉及到的架构方面的内容,也不太能用到复杂的泛型,所以一直觉得这里设计的比较尴尬

期待以后的java能够改进这里

java 泛型上下限的例子,布布扣,bubuko.com

java 泛型上下限的例子

上一篇:Java杂谈三之判断素数以及穷举素数


下一篇:基于ECS搭建云上博客——2.安装 Apache HTTP 服务