意义不同
- ? extends T 表示上界是T
- ? super T 表示下界是T
用法不同
以List为例
List<? extends T> 表示List中存放的都是T或者T的子类型
List<? extends Number> foo = new ArrayList<Number>();
List<? extends Number> foo = new ArrayList<Integer>();
List<? extends Number> foo = new ArrayList<Double>();
foo确定了上界,所以可以从foo中读取到Number对象
而不知道下界,所以foo可能是存储Number子类型的List,不能写入Number对象,同时不知道是哪一种子类型(Integer写Double或Double写Integer),所以写哪一种对象都是不合适的。
List<? super T>表示List中存放的都是T或者T的父类型
List<? super Integer> foo = new ArrayList<Integer>();
List<? super Integer> foo = new ArrayList<Number>();
List<? super Integer> foo = new ArrayList<Object>();
foo确定了下界但是不知道上界,所以读取的话只能保证读到的是Object对象。
而可以确定下界,所以可以向foo中写入Integer和Integer子类型对象。
总结
? extends T 可以读取到T对象,而不能写入T对象和T的子对象
? super T 可以读取到Object对象,可以写入T对象和T的子对象
若想既可以读取又可以写入,则不要用通配符,直接用T
类似于消费者生产者模式
? extends T 只读, ? super T 只写入
经典用法
public class Collections {
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
for (int i = 0; i < src.size(); i++)
dest.set(i, src.get(i));
}
}
}