为什么要有这个
在java中
//经理是员工的子类
Pair<Employee> e=new Pair<Manager>();
上述代码报错 尽管在语义上没什么问题 既然限制放员工 我放的是经理 经理是员工的子类 不也是员工吗 报什么错啊
如果想让这个等式成立 就需要使用通配符类型
通配符类型
(Pair<? extends Employee> p) 表示任何泛型Pair类型,它的类型参数是Employee的子类 这里同样也支持Employee 也就是说?表示的是Employee或者它的子类
//属性的声明
public class Pair<T>
{
private T first;
private T second;
public Pair(T first, T second) {
this.first = first;
this.second = second;
}
public T getFirst() { return first; }
public T getSecond() { return second; }
public void setFirst(T newValue) { first = newValue; }
public void setSecond(T newValue) { second = newValue; }
}
//当T为? extends Employee 时set方法的声明
void setFirst(Pair<? extends Employee> p)
Pair<Manager> managerBuddies = new Pair<>(ceo, cfo);
Pair<? extends Employee> wildcardBuddies = managerBuddies; // OK
wi1dcardBuddies.setFirst(lowly Employee); // compile-time error
调用setFirst方法时将会报错 因为编译无法知道具体调用的是哪个类型
此时setFirst内部调用first=newValue 而first声明的类型为? extends Employee
这个声明是无法赋值的 它表示的是[Employee,…及其子类的集合] 单独赋一个值显然是不行的
但是使用具体的getFirst就不存在这个问题 只需将getFirst的返回值赋给一个Employee的引用完全合法
通配符的超类限定(下界)
与类型限定相比 通配符限定附加了一个能力 即 超类型限定(supertype bound)
? super Manager ?代表的类型参数只能是Manager的超类型或者Manager直观的将带有超类型的通配符可以向泛型对象写入 带有子类型的通配符可以从泛型对象读取
Pair<Manager> managerBuddies = new Pair<>(ceo, cfo);
Pair<? super Manager> wildcardBuddies = managerBuddies; // OK
wildcardBuddies.setFirst(aManager);//传入Manager类型
void setFirst(? super Manager);
? super Manager getFirst();
编译器无法知道setFirst方法的具体类型
因为下界规定了元素的最小粒度下限 实际上放宽了限制 根据限定 Object类可以作为参数传入 任何类型都可以赋值给Object 所以可以传入任何对象?? 显然是不行的
Pair<? super Manager> wildcardBuddies = new Pair<Math>(); //报错
Pair<? super Manager> wildcardBuddies = new Pair<Object>();//不报错
wildcardBuddies.setFirst(new subManager("Gus Greedy", 800000, 2003, 12, 15));//不报错
wildcardBuddies.setFirst(new Object());//报错
那可不可以这样理解
Manager有的方法父类不一定有 所以调用这个方法时不能接受类型为Employee或Object的参数 只能传递Manager类型的对象或者某个子类型(Executive对象) 但是调用getFirst,不能保证返回对象的类型 只能把它赋给Object
来源:CSDN
作者:qq_40184765
链接:https://blog.csdn.net/qq_40184765/article/details/104111745