<? extends T>和<? super T>理解与使用
参考文章连接:<? extends T>和<? super T>理解与使用
含义理解:
? extends T与?super T两者用于泛型对象的读取和插入操作:
? extends T:子类限定,被其修饰的对象只能进行读取操作,不能增删。
? super T:超类限定,被其修饰的对象只能进行增删操作,不能读取。
List<? extends T>:表示该集合中存在的都是类型T的子类,包括T自己。
而List<? super T>:表示该集合中存的都是类型T的父类,包括T自己。
在 Java 泛型中,? extends T 和 ? super T 是两种通配符,用于限制类型参数的范围。这两种通配符分别代表上界通配符(Upper Bounded Wildcard)和下界通配符(Lower Bounded Wildcard)。
? extends T(上界通配符):
当我们希望表示某个类型是 T 或其子类(即 T 的上界)时,可以使用 ? extends T。这意味着我们可以处理 T 类型或其任何子类的对象。
例如,考虑一个方法,它接受一个 List,但我们希望这个 List 的元素类型是 Number 类型或其子类(例如 Integer、Double 等):
public static void processNumbers(List<? extends Number> numbers) {
// ...
}
这里,List<? extends Number> 表示一个元素类型是 Number 或其子类的列表。
? super T(下界通配符):
当我们希望表示某个类型是 T 或其父类(即 T 的下界)时,可以使用 ? super T。这意味着我们可以处理 T 类型或其任何父类的对象。
例如,考虑一个方法,它接受一个 List,但我们希望这个 List 的元素类型是 Integer 类型或其父类(例如 Number、Object 等):
public static void processIntegers(List<? super Integer> integers) {
// ...
}
这里,List<? super Integer> 表示一个元素类型是 Integer 或其父类的列表。
List<? extends T> 和 List<? super T>
List<? extends T> 和 List<? super T> 是 Java 泛型中的两种不同类型的通配符,它们有不同的限制和使用场景。
List<? extends T> 表示列表中的元素是 T 类型或者是其子类型。这种类型的列表是只读的,因为我们无法确定实际类型,所以不能添加元素。如果试图添加一个 T 类型的元素,我们无法保证这个元素是列表实际元素类型的子类型,这可能破坏类型安全。
相反,List<? super T> 表示列表中的元素是 T 类型或者是其超类型(父类型)。这种类型的列表允许添加元素,因为我们知道这个列表可以容纳 T 类型及其子类型的对象。这是因为,如果列表的实际类型是 T 的父类型,那么 T 类型的元素和其子类型的元素都可以安全地添加到列表中。但是,从这种类型的列表中读取元素时,我们只能确定元素是 Object 类型(或其他适当的超类型),因为我们无法确定实际类型。
简单地说,List<? extends T> 限制了我们可以添加的元素类型,因为我们不能确定列表的实际类型。而 List<? super T> 允许我们添加元素,因为它可以确保添加的元素至少是列表实际元素类型的子类型。这些限制有助于保持类型安全,并在不同的使用场景中提供有用的功能。例如,List<? extends T> 在只需要读取元素的情况下很有用,而 List<? super T> 在需要添加元素时很有用。