class Fruit{}
class Apple extends Fruit{}
Fruit[] fruit=new Apple[10];
fruit[0]=new Apple();//0k
fruit[0]=new Fruit()//exception runtime
List<Fruit> flist=new ArrayList<Apple>();//不能将一个Apple的容器赋值给一个Fruit容器,编译错误 incompatible error
这可以使用通配符来解决
Holder<? extends Fruit> fruit=Apple;ok
Fruit p=fruit.get();ok
Apple d=fruit.get(); ok
fruit.set(new Apple()); //Cannot call set()? Extends Fruit 编译器并不能了解这里需要Fruit的哪个子类型,不会接受任何类型的Fruit,编译器将直接拒绝对参数列表中涉及通配符的方法调用。
15.10.2 逆变
超类型通配符,List<? super Apple> apples 可以向其中添加对象
apples.add(new Apple());ok
apples.add(new Jonathan());ok
//apples.add(new Fruit());//Error
Apple是下界,向这样的List中添加Fruit是不安全的。
15.10.3 无界通配符
无界通配符<?> “任何事物”,使用无界通配符好像等价于使用原生类型
static<T> void wildSupertype(Holder<? super T> holder,T arg){
holder.set(arg);
//T t=holder.get();//Error
//Incompatible types:found Object
Holder将持有任何类型的的组合,而Holder<?>将持有具有某种具体类型的同构集合,因此只是想其中传递Object。