一、需要通配符的原因
假设类Manager继承Employee,并且有如下的范型Pair类
class Pair<T> { private T first; private T second; public Pair() { first = null; second = null; } public Pair(T first, T second) { this.first = first; this.second = second; } public static <T> Pair<T> makePair(Class<T> cl) { try { return new Pair<>(cl.getConstructor().newInstance(), cl.getConstructor().newInstance()); } catch (Exception e) { return null; } } public T getFirst() { return first; } public T getSecond() { return second; } public void setFirst(T newValue) { first = newValue; } public void setSecond(T newValue) { second = newValue; } }View Code
如下是能够通过编译并且正常运行
Pair<Manager> pm = new Pair<>(new Manager("fr", 100, 1000, 1,1), new Manager("sec", 2100, 2000, 2,1));
那么如下是否也会正常运行呢?
Pair<Employee> pm = new Pair<>(new Manager("fr", 100, 1000, 1,1), new Manager("sec", 2100, 2000, 2,1));
都能正常运行
但是如果使用如下的调用方式是不能通过编译
public static void printBuddies(Pair<Employee> p) { Employee first = p.getFirst(); Employee second = p.getSecond(); System.out.println(first.getName() + " and " + second.getName()); } Pair<Manager> pm = new Pair<>(new Manager("fr", 100, 1000, 1,1), new Manager("sec", 2100, 2000, 2,1)); printBuddies(pm);
传入的是Pair<Manager>类型,但是printBuddies需要的是Pair<Employee>,虽然Manager是Employee的子类,但是在范型里面他们是两个完全不同的类型
所以需要使用通配符的概念
public static void printBuddies(Pair<? extends Employee> p) {
。。。。。
}
这里使用?的方式
二、通配符的类型
上界通配符:? extends T
下界通配符:? super T
无限定通配符:?
假设:B extends A, C extends B; 即:C -> B -> A
那么:pair<? extends B> 能够传入的参数是:pair<C>、pair<B>
pair<? super B> 能够传入的参数是:pair<B>、pair<A>
上界通配符的特性是:不能往里存,只能往外取。(其实是可以存,但是如果进行存的话会破坏类型的安全;因为设置的可以是C或者B,那么设置的类型就会出现多样性)
下界通配符的特性是:只能能往里存,不能往外取。(读取的话,因为不知道是B或者A,所以如果是get的话则会返回Object)
无限定通配符的特性是:读取和设置的都是object的对象。(如果只是判空或者设置为空的操作则适合使用无限定通配符)
标签:范型,java,通配符,second,Pair,new,public,first From: https://www.cnblogs.com/czwlinux/p/16767381.html