参考链接:https://blog.csdn.net/qq_41622739/article/details/91307264
package com.ygl.demo4;
public class Biology {
}
package com.ygl.demo4;
public class Person extends Biology{
}
package com.ygl.demo4;
public class Teacher extends Person{
}
<? extends E>,表示限定集合元素的上边界类型
此时list集合是不能添加元素的,因为? extends Person此时只是限定了list里面的元素是Person类型或者是继承与Person的类,并没有给定一个具体的类型。
ArrayList<? extends Person> list = new ArrayList<>(); //? extends Person,限定上边界,表示Person子类及Person类
ArrayList<? extends Person> list1 = new ArrayList<Biology>();//报错
ArrayList<? extends Person> list2 = new ArrayList<Person>();
ArrayList<? extends Person> list3 = new ArrayList<Teacher>();
list.add(new Biology()); //因为类型不确定,所以无法添加元素
list.add(new Person());
list.add(new Teacher());
Person person = list.get(0); //可以取出元素
<? super E>,表示限定集合元素的下边界类型
此时list集合是允许添加Person类及其子类,因为? super Person此时只是限定了list里面的元素是Person类型或者是Person类的父类,当添加一个person的父类时候会失败,因为Person类的父类可能有很多,并不能确实其父类的类型,相反,添加Person类的子类是可以的,因为子类可以向上转型为父类类型。
ArrayList<? super Person> list = new ArrayList<>(); //? super Person,限定下边界,表示Person父类及Person类
ArrayList<? super Person> list1 = new ArrayList<Biology>();
ArrayList<? super Person> list2 = new ArrayList<Person>();
ArrayList<? super Person> list3 = new ArrayList<Teacher>();
list.add(new Biology()); //因为类型不确定,所以无法添加元素
list.add(new Person());
list.add(new Teacher());
Person person = (Person) list.get(0); //可以去除元素
<? extends E>和<? super E>的存取原则
如果你想从一个数据类型里获取数据,使用 ? extends 通配符
如果你想把对象写入一个数据结构里,使用 ? super 通配符
如果你既想存,又想取,那就别用通配符。
PECS原则
PECS指“Producer Extends,Consumer Super”。
如果你是想遍历collection,并对每一项元素操作时,此时这个集合是生产者(生产元素),应该使用 Collection<? extends Thing>。
如果你是想添加元素到collection中去,那么此时集合是消费者(消费元素)应该使用Collection<? super Thing>。