泛型上下限的使用场景

假设我们有两个泛型的 List

List<A> listA;
List<B> listB;

A,B 具有继承关系,具体定义如下:

class A {
	public char aFun(){
    	return 'A';
    }
}

class B extends A {
	public char bFun(){
    	return 'B';
    }
}

考虑下面两种使用场景:

public void Main(String[] args){
	...
    List<B> bList = ...;
    List<A> aList = bList;
    for(A a: aList){
    	a.aFun();
    }
    ...
}
public void Main(String[] args){
	...
    List<A> aList = ...;
    List<B> bList = bList;
    aList.add(new A());
    ...
}

Java 的泛型主要就是为了兼容上面两种的使用场景。

上面两份代码都会编译出错,原因 Java 编译器无法解决泛型的类型转换(即使具有继承关系)。于是就需要使用 <? extends T>,<? super T> 来帮助编译器进行编译时的类型检查。

  • super:你的泛型类(对象/方法)需要对传入的参数做限制
  • extends:你的泛型类(对象/方法)需要对返回值做限制

于是,上面两份代码变化:

public void Main(String[] args){
	...
    List<B> bList = ...;
    List<? extends A> aList = bList;
    for(A a: aList){
    	a.aFun();
    }
    ...
}
public void Main(String[] args){
	...
    List<A> aList = ...;
    List<? super B> bList = aList;
    aList.add(new B());
    ...
}