泛型中上下界限定符extends 和 super有什么区别?
面试回答¶
面试官: 泛型里的 <? extends T> 和 <? super T> 有什么区别?
你:
核心就是读写权限的差别,业内有个口诀叫 PECS(Producer Extends, Consumer Super)。
-
? extends T是上界通配符,代表 T 或它的任意子类。这种集合只能往外读,不能往里写(除了 null)。因为编译器只知道里面装的是“某种 T 的子类”,但你往里放一个 T,它不一定是这个具体的子类型,所以写操作不安全。但读出来的东西一定可以当作 T 来用。 -
? super T是下界通配符,代表 T 或它的任意父类。这种集合只能往里写 T 或其子类,读取只能当 Object。因为集合的实际类型可能是 T 的某个父类,你放一个 T 的子类进去一定是安全的(向上转型)。但取出来时,编译器只知道它是“某个 T 的父类”,具体是啥不确定,只能当作 Object。
实战场景:
-
你写一个方法,想遍历一个集合里的元素,只读不写,参数就用
List<? extends T>。 -
你写一个方法,想把数据放进集合,只写不读(或很少读),参数就用
List<? super T>。
一个经典例子:Collections.copy(List<? super T> dest, List<? extends T> src),src 是生产者(extends),dest 是消费者(super)。
Mermaid 时序图:编译器对 extends 和 super 的读写校验

一句话:extends 适合生产者(读),super 适合消费者(写)。 记住这个,泛型方法设计不会乱。