Java 泛型super和extend

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

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

生产者使用extends

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

消费者使用super

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

你可能感兴趣的:(Java)