泛型
说明
? extends T
:
这种形式的通配符表示的是一个上界限定,表示泛型类型必须是 T
类型或其子类型。换句话说,你可以将此通配符用于读取数据,但无法向其中写入数据。
因为放入的数据都是 extends T
,
? super T
:
这种形式的通配符表示的是一个下界限定,表示泛型类型必须是 T
类型或其父类型。换句话说,你可以将此通配符用于写入数据,但无法从中读取数据。
例子1
? extends T
:
1 | import java.util.ArrayList; |
在这个例子中,List<? extends Number>
表示这个列表的元素类型必须是 Number
或其子类型。你可以安全地读取列表中的元素并将其向上转型为 Number
类型,但由于无法确定列表的实际类型,因此无法向其中添加任何元素。
? super T
:
1 | import java.util.ArrayList; |
在这个例子中,List<? super Integer>
表示这个列表的元素类型必须是 Integer
或其父类型。你可以安全地向列表中添加 Integer
类型的元素,但无法确定从列表中读取的元素的确切类型,因此只能将其转型为 Object
类型。
总的来说,? extends T
和 ? super T
是用于泛型类型限定的通配符,用于表示类型的上界和下界。使用这些通配符可以增强代码的灵活性和安全性,但需要谨慎使用,因为它们可能会使代码变得更加复杂和难以理解。
例子2
通过一个具体的示例来说明 ? extends T
和 ? super T
的用法。我们以 Fruit
类及其子类 Apple
和 Banana
为例。
1 | java复制代码class Fruit { |
? extends T
示例:
我们创建一个方法 printFruitInfo
,它接受一个泛型类型的列表,该列表的元素类型必须是 Fruit
类型或其子类型。在这个方法中,我们只打印每个元素的信息。
1 | java复制代码import java.util.List; |
在这个例子中,printFruitInfo
方法接受一个类型为 List<? extends Fruit>
的列表。因此,它可以接受 Apple
类型的列表和 Banana
类型的列表,因为它们都是 Fruit
类型的子类型。
? super T
示例:
我们创建一个方法 addFruit
,它接受一个泛型类型的列表,该列表的元素类型必须是 Fruit
类型或其父类型。在这个方法中,我们尝试向列表中添加一个新的 Fruit
对象。
1 | java复制代码import java.util.List; |
在这个例子中,addFruit
方法接受一个类型为 List<? super Fruit>
的列表。因此,它可以接受 Fruit
类型的列表和 Object
类型的列表,因为它们都是 Fruit
类型的父类型。但它无法接受 Apple
类型的列表,因为 Apple
类型不是 Fruit
类型的父类型。