类似有<? extends T> 和 <? super T>两种通配符,之所以有这样的定义估计也是为了类似实现多态的意味,因为比如Super a=new Child()(Child是Super的子类),但 ArrayList<Child>的实例不能付给ArrayList<Super>类型的引用,他们没有继承关系,所以设计者才想出用通配符,比如:

ArrayList<? extends Super> a=new ArrayList<Child>(); 或者

ArrayList<? extends Super> a=new ArrayList<Child1>();或者

ArrayList<? extends Super> a=new ArrayList<Super>();

但此时a这个引用只知道他所引用的对象泛型参数是Super或其子类,它并不知道它所引用的对象的类型参数是什么,所以它也无法生成一个规则来判断set或add的参数是否合法,此时执行a.set(new Child())或a.add(new Child())之类的方法是不被允许的,因为a这个引用无法判断传入的参数是否合法,所以set add 之类的方法不被允许,然后get是被允许的,因为a这个引用知道返回的最高级的类是Super,所以它可以生成一个规则即用一个Super类型或其父类的引用去引用get的结果是ok的。

对于<? super T>,可以ArrayList<? super Child> a=new ArrayList<Child>(); 或者

ArrayList<? super Child> a=new ArrayList<Super>();或者

ArrayList<? super Child> a=new ArrayList<Object>();

但此时a这个引用只知道他所引用的对象泛型参数是Child或其父类,此时它不知道它所引用的对象的类型参数最低是child,所以它可以生成一个规则即set或add Child或其子类都是ok的。所以这种泛型是可以set或add的,但他不能进行get操作,因为他不知道get出来的类型的上限是什么,所以他也无法生成判断规则,所以它不能get。

其实如果虚拟机要是能获得a引用的对象的类型参数就能解决不能set或get的问题,但目前这是不能做到的,因为虚拟机里根本没有泛型,在虚拟机类存放的是用类型参数替换后的对象。