12.8 通配符类型

固定的泛型类型系统使用起来并没有那么令人愉快,类型系统的研究人员知道这一点已经有一段时间了。Java的设计者发明了一种巧秒的(仍然是安全的)“解决方案”:通配符类型。

例如,通配符类型

Pair<? extends Employee>

表示任何泛型Pair类型,它的类型参数是Employee的子类,如Pair<Manager>,但不是Pair<String>。

假设要编写一个打印雇员对的方法,像这样:

public static void printBuddies(Pair<Employee> p){
    Employee  first = p.getFirst();
    Employee  second = p.getSecond();
    System.out.println(first.getName() + "and" + second.getName() + "are buddies");
}

正如前面讲到的,不能将Pair<Manager>传递给这个方法,这一点很受限制。解决的方法很简单:使用通配符类型:

public static void printBuddies(Pair<? extends Employee> p)

类型Pair<Manager>是Pair<? extends Employee>的子类型

使用通配符会通过Pair<? extends Employee>的引用破坏Pair<Manager>吗?

Pair<Manager> managerBuddies = new Pair<>(ceo, cfo);
Pair<? extends Employee> wildcardBuddies = managerBuddies;
wildcardBuddies.setFirst(lowlyEmployee);

这可能不会引起破坏。对setFirst的调用有一个类型错误。要了解其中的缘由,请仔细看一看Pair<? extends Employee> 其方法似乎是这样的:

? extends Employee getFirst()
void setFirst(? extends Employee)

这样将不可能调用setFisrt方法。编译器只知道需要某个Employee的子类型,但不知道具体是什么类型。它拒绝传递任何特定的类型。毕竟?不能用来匹配

使用getFirst就不存在这个问题:将getFirst的返回值赋给一个Employee的引用完全合法。

这就是引入有限定的通配符的关键这外。现在已经有办法区分安全的访问器方法和不安全的更改器方法了。

results matching ""

    No results matching ""