1 回答
TA贡献1869条经验 获得超4个赞
当您声明时:
Pair<? super Manager> pm2 = ...
Pair接受泛型的方法可以替换泛型 byManager和它的子类(在您的情况下Executive)。
所以从逻辑上讲,当您使用泛型调用方法时,您将得到以下结果:
Pair<? super Manager> pm2 = ...;
pm2.setFirst(new Executive()); // compile
pm2.setFirst(new Manager()); // compile
pm2.setFirst(new Employee()); // doesn't compile
最后就像你没有使用任何通配符:
Pair<Manager> pm2 = ...;
pm2.setFirst(new Executive()); // compile
pm2.setFirst(new Manager()); // compile
pm2.setFirst(new Employee()); // doesn't compile
因此,在您的示例中,您使用的下限通配符是无助的。
事实上,它是最糟糕的,因为您将它用于从泛型类型中放入和获取东西,而下界通配符旨在放入东西,而不是从中获取东西。
而您必须执行的强制转换会破坏通用目的(类型安全):
Employee ex1 = (Employee) pm2.getFirst(); // OK
Manager ex2 = (Manager) pm2.getSecond(); // OK
Executive ex3 = (Executive) pm2.getSecond(); // why is allowed?
那么我们需要如何使用Pair<? super Manager>呢?
因为我们希望泛型集合Pair可以分配给其他Pair类型以“放入”东西。
非常常见的用例是声明一个接受泛型类型的方法<? super>。
但在这种情况下,我们希望将未知类型限制为特定类型或超类型,以防止“放置”可能危及作为参数传递的泛型类型的类型安全的东西。
例如,假设您需要一个接受 a PairofManager实例并将事物放入 this 的方法Pair。您不希望客户端方法可以传递 aPair<Executive>否则如果我们添加 a 可能会破坏通用安全性Manager,因为 aManager不是Executive实例所必需的。这里是下界通配符的主要作用。
示例代码来说明:
public void putStuff(Pair<? super Manager> managers) {
if (...){
managers.setFirst(new Manager());
}
else if (...){
managers.setFirst(new Executive());
}
}
现在只有类型或超类型Manager的Pair泛型类型可以传递:
putStuff(new Pair<Manager>(...)); // compile
putStuff(new Pair<Employee>(...)); // compile
putStuff(new Pair<Executive>(...)); // doesn't compile
添加回答
举报