在 Java 泛型中存在通配符的概念:

<? extends C>是上界通配符
<? super C>是下界通配符

接下来对这些进行说明,先定义几个类:

1
2
3
4
5
6
7
class A{};

class B extends A{};

class C extends B{};

class D extends B{};

为什么会出现这个呢?

1
2
A a = new B();
List<A> list= new ArrayList<B>(); // 报错Type mismatch

这是因为无论A和B有什么关系,通常,List和List没有什么联系。
那么我们通过<? extends B>解决这个问题:

1
2
3
4
5
public class Test{
public static void main(String[] args) {
List<? extends A> list = new ArrayList<B>(); //OK
}
}

这里用的是 ArrayList 做例子,但并不是只针对集合,是针对类似集合出现的问题的情景。

局限性

上界<? extends B>不能往里存,只能往外取

  • add() 编译器只知道类型是B或者B的子类,所以可能是B、C、D其中的一个类型,但为了保证类型的安全就不能添加除了null之外的元素,即使是B本身也不行。(因为B不能代表C或者D)
  • get() 此时不知道返回的是B、C、D其中哪个类型,所以返回类型是B

下界<? super B>可以存(存的只能是B或者B的子类),但往外取只能放在Object对象里

  • add() 可以添加B、C、D(因为C或D可以代表B)
  • get() 因为是下边界,所以返回类型只能是Object,所以说它的get()受到限制