Java 泛型super和extend

  • 假设:Men extends Person
  • 但是不能 List<Person> list = new List<Men>(); 会报错!
  • 因为: Men is-a Person  存在继承关系
  • 但是:List<Men> is-not-a List<Person>   不存在继承关系
  • 这让泛型用起来很不舒服,为解决这个问题,所以:
  • ? 通配符类型
  • <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类
  • <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
  • 现在:List<?extends Person> list = new List<Men>(); 就合法了。

请记住PECS原则:生产者(Producer)使用extends,消费者(Consumer)使用super。

生产者使用extends

List<? extendsPerson>表示该list集合中存放的都是Person的子类型(包括Person自身),由于Person的子类型可能有很多,但是我们存放元素时实际上只能存放其中的一种子类型(这是为了泛型安全,因为其会在编译期间生成桥接方法<Bridge Methods>该方法中会出现强制转换,若出现多种子类型,则会强制转换失败)。因此你不能往该列表中添加任何元素,(因为你不知道里面到底存储的是什么类型)。List<? extends Person>不能添加元素,但是由于其中的元素都有一个共性--有共同的父类,因此我们在获取元素时可以将他们统一强制转换为Person类型,相当于一个只读List。

消费者使用super

对于List<? super Men>其list中存放的都是Men的父类型元素(包括Men),我们在向其添加元素时,只能向其添加Men的子类型元素(包括Men类型),这样在编译期间将其强制转换为Men类型时是类型安全的,因此可以添加元素但是由于该集合中的元素都是Men的父类型(包括Men),其中的元素类型众多,在获取元素时我们无法判断是哪一种类型,故设计成不能获取元素,相当于一个只写List。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值