1.通配符概念
通配符类型中,允许类型参数变化。例如,通配符类型
Pair<? extends Employee>
表示任何泛型类型Pair类型,它的类型参数是Employee的子类,如Pair<Manager>。
2.通配符的限定
通配符限定与类型变量限定十分类似,但是,还有一个附加的功能,即可以指定一个超类型限定,如下所示:
? super Manager
这个通配符限制为Manager的所有超类。
直观地讲,带有超类型限定的通配符(super)可以向泛型对象写入(调用set方法),带有子类型限定(extends)的通配符可以从泛型对象读取(调用get方法)。
总结:
- 假设方法do(Pair<? extends Employee>),则可传入do方法的类型为Pair<Manager>或Pair<Employee>。
- 假设方法do(Pair<? super Manager>),则可传入do方法的类型为Pair<Employee>或Pair<Object>
3.无限定通配符
类型Pair<?>有如下方法:
- ? getFirst()
- void setFirst()
Pair<?>和原始的Pair本质的不同在于:可以用任意Object对象调用原始Pair类的setFirst()方法。而Pair<?>无法调用setFirst()方法。
为什么要使用这样脆弱的类型?因为,带有通配符的版本可读性更强。
4.通配符捕获
假设编写一个交换成对元素的方法:
public static void swap(Pair<?> p)
在交换的时候必须临时保存第一个元素,然而通配符不是类型变量,因此以下代码是非法的:
? t = p.getFirst();
p.setFirst(p.getSecond());
p.setSecond(t);
这时候我们可以写一个辅助方法swapHelper,如下:
public staitc<T> void swapHelper(Pair<T> p) {
T t = p.getFirst();
p.setFirst(p.getSecond);
p.setSecond(t);
}
现在可以由swap调用swapHelper:
public static void swap(Pair<?> p) {swapHelper(p);}
在这种情况下,swapHelper方法的参数T捕获通配符。