通配符类型 <? super T> 和 <? extends T> 的深入解析:揭秘泛型类型
2024-03-16 01:51:43
泛型类型:解开 <? super T> 和 <? extends T> 之谜
前言
泛型类型是 Java 中强大的工具,它允许你创建可以处理不同类型对象的类和方法。在泛型类型中,通配符类型,例如 <? super T> 和 <? extends T> ,用于指定类型变量 T 的上下界。在本文中,我们将深入探讨这两种通配符类型的区别,并了解何时使用它们。
<? super T>:超类型
<? super T> 指定 T 的超类型。换句话说,它允许你使用 <? super T> 类型的变量来引用 T 类型的对象或其任何超类型(父类或接口)的对象。例如,假设我们有一个父类 Animal
和一个子类 Dog
。那么:
List<? super Dog>
可以引用List<Animal>
或List<Dog>
对象。- 它不能 引用
List<Object>
或任何其他不包含Animal
类型对象的列表。
用途:
<? super T> 非常适合以下情况:
- 当你想从一个超级类型集合中读取元素时。
- 当你想将一个元素添加到一个超类型列表中时。
<? extends T>:子类型
<? extends T> 指定 T 的子类型。换句话说,它允许你使用 <? extends T> 类型的变量来引用 T 类型的对象或其任何子类型(子类或实现类)的对象。延续之前的示例:
List<? extends Animal>
可以引用List<Animal>
或List<Dog>
对象。- 它不能 引用
List<Object>
或任何其他不派生自Animal
类型对象的列表。
用途:
<? extends T> 适用于以下情况:
- 当你想将一个元素添加到一个子类型列表中时。
- 当你想从一个子类型集合中获取一个元素时。
<? super T> 和 <? extends T> 的区别
- <? super T> 允许你添加 T 类型的对象,因为 T 的超类型也可以添加。
- <? extends T> 不允许 你添加 T 类型的对象,因为 T 的子类型不能添加。
示例代码
// 超类型通配符
List<? super Dog> list1 = new ArrayList<>();
list1.add(new Dog()); // 允许添加 Dog 对象
list1.add(new Animal()); // 允许添加 Animal 对象
// 子类型通配符
List<? extends Animal> list2 = new ArrayList<>();
list2.add(new Animal()); // 不允许添加 Animal 对象
list2.add(new Dog()); // 不允许添加 Dog 对象
结论
理解 <? super T> 和 <? extends T> 通配符类型对于有效使用 Java 泛型至关重要。通过了解它们之间的区别,你可以创建灵活且可重用的代码。
常见问题解答
1. 什么时候使用 <? super T>?
当你需要一个可以引用 T 类型的对象或其超类型对象的列表或集合时。
2. 什么时候使用 <? extends T>?
当你需要一个只能引用 T 类型的对象或其子类型对象的列表或集合时。
3. <? super T> 可以添加 T 类型的对象吗?
是的,它可以。
4. <? extends T> 可以添加 T 类型的对象吗?
不,它不能。
5. 通配符类型有什么好处?
它们提供灵活性,让你可以编写可处理不同类型对象的代码。