Java泛型

public class Food {}
class Fruit extends Food {}
class Apple extends Fruit {}
class Banana extends Fruit{}

class GenericTest {
    public void testExtends(List<? extends Fruit> list){
        //报错,extends 为上界通配符,只能取值,不能放.
        //因为 Fruit 的子类不只有 Apple 还有 Banana,这里不能确定具体的泛型到底是 Apple 还是Banana,所以放入任何一种类型都会报错
        list.add(new Apple());  // 报错
        //可以正常获取
        Fruit fruit = list.get(1);
    }
    public void testSuper(List<? super Fruit> list){
        //super 为下界通配符,可以存放元素,但是也只能存放当前类或者子类的实例,以当前的例子来讲,
        //无法确定 Fruit 的父类是否只有 Food 一个(Object 是超级父类)
    }
}

具体解释一下:

对于定义的 List<? extends Fruit> list,给他初始化的时候,指定的类型必须是Fruit或Fruit的子类,即

List<? extends Fruit> list = new ArrayList<Apple>(); // compile success
List<? extends Fruit> list2 = new ArrayList<Food>(); // compile fail

所以往里面添加的时候你没法知道具体是哪个子类,比如初始化为new ArrayList(),然后添加是Banana 类型,这样就导致了类型错误。因此list在这里是不能添加元素的,只能获取,因为可以知道里面的元素一定是Fruit及其子类型的一种,因此可以用Fruit去接收。
那肯定有人会有这样的疑问?那不能添加岂不是就一个空列表,还有什么意义呢。这里就要说到使用场景了,一个都是用在方法的形参里面定义,在传参的时候就传的是一个有值的列表。当然如果不是在形参中你也要这么用,当然也是可以的,如下:

List<? extends Fruit> list;
List<Apple> list2 = new ArrayList<Apple>();
list2.add(new Apple());
list2.add(new Apple());
list2.add(new Apple());
list = list2;
list.size();

对于List<? super Fruit> list就是同样的道理了,初始化的类型必须是Fruit及其父类,因此可以放心的往里面添加Fruit及其子类,但是从列表里面取得时候就只能用Object类去接收,从定义中无法知道具体是Fruit或它的哪个父类。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值