Java 通配符类型的限定

  1. ? extends T 表示任何实现类型 T 的子类型范围
  2. ? super T 表示任何类型 T 的父类范围

Java核心技术卷Ⅰ有一句话:带有超类型的限定的通配符允许你写入一个泛型对象,而带有子类型限定的通配符允许你读取一个泛型对象(Wildcards with supertype bounds let you write to a generic object, while wildcards with subtype bounds let you read from a generic object)

这句话怎么理解呢?

假定有两个类:

/* 人类 */
public class Person {
}

/* 学生类 */
public class Student extends Person {
}

? extends T 表示任何实现类型 T 的子类型范围

List<? extends Person> list = new ArrayList<>();
list.add(new Student()); // 编译错误,类型不兼容
Person person = list.get(0); // 允许

因为 list 的类型参数是任何实现了 Person 类的子类,所以 list 可能是 List<Teacher>,也可能是 List<Student>,编译器并不知道可能传入的类型参数是什么,所以拒绝添加

但是你可以从中得到一个 Person 类型的对象,因为你得到的对象类型一定是 Person 类的子类

? super T 表示任何类型 T 的父类范围

List<? super Person> list = new ArrayList<>();
list.add(new Student()); // 允许
Object person = list.get(0); // 只能读取为 Object 类型

你可以往 list 里添加学生,因为 list 的类型参数一定是 Student 的父类,父类引用指向子类对象是没有问题的

但是你从 list 取出元素时,并不知道具体的父类是什么,唯一能保证的是 Java 中所有类的超类 Object,所以你只能从中取出 Object 类型的元素


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。