class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
以上面的继承关系说明
public static void main(String[] args) {
//ArrayList不是ArrayList的父类或同类,否则导致一个Cat对象能添加到Dog集合中
//所以需要泛型的存在
// ArrayList list = new ArrayList();
// list.add(new Dog());
// ArrayList temp = list;
// temp.add(new Cat());
//上界通配符,能接收同类或子类,能取不能设置修改
ArrayList list = new ArrayList();
ArrayList extends Animal> temp = list;
ArrayList extends Dog> temp1 = list;
// temp.add(new Dog()); //Error
// temp.add(new Animal()); //Error
// temp.add(new Cat()); //Error
Animal animal = temp.get(0);
//下届通配符,能接收父类或同类
ArrayList list2 = new ArrayList();
ArrayList super Animal> temp2 = list2;
ArrayList super Dog> temp3 = list2;
temp2.add(new Animal());
temp2.add(new Dog());
temp2.add(new Cat());
// Animal object = temp2.get(0); //Error
Object o = temp3.get(0);
}
总结:
通配符解决的是泛型与泛型之间赋值指向的问题,例如ArrayList 与 ArrayList
正常情况的set和get
set:能够插入设置泛型同类和子类,存在多态
ArrayList list2 = new ArrayList();
list2.add(new Dog());
get:拿到索引指定对象,存在多态
ArrayList list = new ArrayList();
Animal a= list.get(0);
上界通配符extends:赋值后,接收同类或子类,实际对象从子类变成了父类,内部元素能get不能set,因为多态存在
set:ArrayList-->ArrayList-->list.add(new Cat())-->等于将一个cat对象插入ArrayList中,这是不被允许的
get:ArrayList-->ArrayList-->Animal a= list.get(0)-->Animal指向一个Dog对象,没问题
下界通配符super:赋值后,接收同类或父类,实际对象从父类变成了子类,内部元素能set不能get,因为多态存在
set:ArrayList-->ArrayList-->list.add(new Dog())-->等于将一个Dog对象添加到一个Animal集合,没问题
get:ArrayList--->ArrayList-->Dog dog = list.get(0);-->等于用子类dog指向一个父类对象,这是不被允许的.除非像上面一样用顶级父类Object来接收,这里不能用Animal来接收,因为它不是Dog的顶级父类,存在Dog extends Animal,Animal extends Life,此时ArrayList--->ArrayList,用Animal来指向父类Life对象显然也是不被允许的