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 类型的元素
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。