Java泛型中的PECS原则是什么呢?这里的PECS全称是Producer extends Consumer super 顾名思义就是生产者继承消费者超级
public class Student<T,K> { private T name; private K age; public Student(T name, K age) { this.name = name; this.age = age; } public T getName() { return name; } public void setName(T name) { this.name = name; } public K getAge() { return age; } public void setAge(K age) { this.age = age; } }
当我们在mangerAge方法中使用extends通配符时,此时的getAge方法可以接收满足? extends Number的对象,但必须用Number来接收,因为程序并不知道你传入的时Double还是Integer。当你想SetAge写入值时,是不允许的,例如在此程序中,你在student.setAge(new Double())传入一个Double类型的参数,Integer显然是无法接收的,只能传入一个null,但会报空指针异常。
public class StudentManager { public static void mangerAge(Student<String, ? extends Number> student){ // public ? extends Number getAge() // 我们需要用Number来接收student.getAge(), // 因为程序不知道你传入的是Integer还是Double,所以要用Number来接收 System.out.println(student.getAge()); // 如果传入的mangerAge方法中Student的参数是<String,Double>, // 你在setAge中传入<String,Integer>能满足Student<String, ? extends Number>,但Double不能接收Integer, // 此处只能传入null,但当你获取Age值时肯定会报空指针异常。 student.setAge(null); } public static void main(String[] args) { Student<String, Integer> s1 = new Student<>("小明", 13); mangerAge(s1); } }
super通配符,当你想写入一个值,只要满足super通配符的要求即可,当你想接收一个值时是不允许的(Object)除外,因为程序并不知道你要传入的类型是哪个
public class StudentManager { public static void mangerAge(Student<String, ? super Integer> student){ // void setAge(? super Integer age) student.setAge(new Integer(18)); System.out.println(student.getAge()); // 18 } public static void main(String[] args) { Student<String, Number> s2 = new Student<>("小明", 13); mangerAge(s2); } }
总结:PECS:Producer extends获取值,使用extends通配符时,能接收(读取)值,不能写入(null除外);Consumer super 写入,消费者使用super通配符时,不能接收(读取)值(Object接收除外),能写入。