但是这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素加入到其中。如下面代码会引起错误:


1 import java.util.List;
2 import java.util.ArrayList;
3
4 public class GeneicTest1{
5
public static void main(String[] args){
6
List<?> list = new ArrayList<String>();
7
list.add("疯狂Java讲义");
8
}
9 }
View Code

设定类型通配符的上限:
当直接使用List<?>这种形式,即表明这个List集合可以是任何泛型List的父类。但还有一种特殊的情形,程序不希望这个List<?>是任何泛型List父类,只希望它代表某一类
泛型List的父类:


1 //定义一个抽象类Shape
2 public abstract class Shape{
3
public abstract void draw(Canvas c);
4 }
View Code


1 //定义Shape的子类Circle
2 public class Circle extends Shape{
3
//实现画图方法,以打印字符串来模拟画图方法实现
4
public void draw(Canvas c){
5
System.out.println("在画布" + c + "上画个圆");
6
}
7 }
View Code


1 //定义Shape的子类Rectangle
2 public class Rectangle extends Shape{
3
public void draw(Canvas c){
4
//实现画图方法,以打印字符串来模拟画图方法实现
5
System.out.println("把一个矩形画在画布" + c + "上");
6
}
7 }
View Code

View Code

上面的错误关键在于List<Circle>并不是List<Shape>的子类,所以不能把List<Circle>对象当成List<Shape>使用。为了表示List<Circle>的父类,可以考虑使用List<?>:


1 import java.util.List;
2 import java.util.ArrayList;
3
4 public class Canvas{
5
//同时在画布上绘制多个形状
6
public void drawAll(List<?> shapes){
7
for(Object obj : shapes){
8
Shape s = (Shape) obj;
9
s.draw(this);
10
}
11
}
12
13
public static void main(String[] args){
14
//下面的代码将会引起错误
15
//drawAll方法的形参类型是List<Shape>而不是List<Circle>
16
List<Circle> circleList = new ArrayList<>();
17
Canvas c = new Canvas();
18
//不能把List<Circle>当成List<Shape>使用
19
c.drawAll(circleList);
20
}
21 }
View Code
上面程序使用了通配符来表示所有的类型。问题是上面的方法实现体显得非常臃肿且繁琐:使用了泛型还需要强制类型转换。
实际上需要一种泛型表示方法,它可以表示所有Shape泛型List的父类,即List<?>可以匹配所有Shape和Shape的子类的List集合,而不用使用强制类型转换。
Java为泛型提供了被限制的泛型通配符。被限制的通配符表示如下:
//它表示所有Shape泛型List的父类
List<? extends Shape>
有了这种被限制的泛型通配符,把上面的Canvas程序改成如下:


1 import java.util.List;
2 import java.util.ArrayList;
3
4 public class Canvas{
5
//同时在画布上绘制多个形状
6
public void drawAll(List<? extends Shape> shapes){
7
for(Shape s : shapes){
8
s.draw(this);
9
}
10
}
11
12
public static void main(String[] args){
13
//下面的代码将会引起错误
14
//drawAll方法的形参类型是List<Shape>而不是List<Circle>
15
List<Circle> circleList = new ArrayList<>();
16
Canvas c = new Canvas();
17
//不能把List<Circle>当成List<Shape>使用
18
c.drawAll(circleList);
19
}
20 }
View Code
List<? extends Shape>:意思是List<>尖括号中只要是Shape或Shape的子类都可以。