泛型中的extend和super

java中经常会看到泛型中使用<? extends T>/<? super T> ,这个回答很好,这里记下我看后的思考。

< ? extends T>

当声明了这样的一个泛型后,实际上其可以指向T或其子类的泛型,主要的一个点是在运行之前,无法确定到底指向的是哪个类型的泛型

  1. 这时JVM为了避免实际指向的类型Tsub1和你想放进去的类型Tsub2产生冲突,所以干脆就不让put了。
  2. 但是读取的时候,完全可以按照T来读取所有的内容,可以理解为多态,父类型引用指向子类型对象,一样可以操作,所以可以get.

<? super T>

这样声明的话,实际上可以指向T或其父类的泛型,同样运行之前无法确定实际指向的类型

  1. 不论指向的是T或其父类型,都能保证T或其子类可以put进去,同样是父类引用指向子类对象,没毛病。
  2. 但是读取的时候就出现问题了,如果不考虑根父类Object,不同类型的东西读出来的时候没有一个统一的类型,不像上边可以统一按照类型T读取。真的想拿出的话就只能按Object拿了。

PECS

一般这个东西都会带一起看,是Producer Extends, Consumer Super的简称,这句话站在集合的角度看比较容易理解

  1. 如果集合作为Producer,那么其他的消费者就要从这个集合中拿东西,相当与get多,就选用extends
  2. 如果集合作为Consumer,那么它就要从别的生产者那里拿东西放到自己里边,相当于put多,就选用super