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