Java泛型中的PECS原则是什么呢?这里的PECS全称是Producer extends Consumer super 顾名思义就是生产者继承消费者超级
- 如下有个实体类,我们需要对它进行操作,探讨PECS
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接收除外),能写入。