在Java泛型中,通配符extends和super是用来限定泛型类型的关键字,它们具有不同的作用和使用场景。以下是两者的异同点:
相同点
- 都是泛型限定符:extends和super都是用于限定泛型类型的,使泛型代码更加灵活和强大。
不同点
-
含义不同:
- extends:表示上界限定,用于限定泛型类型必须是某个类或其子类。在泛型类或泛型方法中使用extends,可以实现对泛型类型的继承限定。例如,
List<? extends Number>表示该列表可以存放Number类型或其子类型的元素。 - super:表示下界限定,用于限定泛型类型必须是某个类或其父类。在泛型类或泛型方法中使用super,可以实现对泛型类型的父类限定。例如,
List<? super Integer>表示该列表可以存放Integer类型或其父类型的元素。
- extends:表示上界限定,用于限定泛型类型必须是某个类或其子类。在泛型类或泛型方法中使用extends,可以实现对泛型类型的继承限定。例如,
-
使用场景不同:
- 消费者使用super:如果需要一个列表来存放T类型的元素(即想把T类型的元素加入到列表中),则需要把这个列表声明成
<? super T>。然而,这种情况下不能保证从中读取到的元素的类型。 - 生产者使用extends:如果需要一个列表来提供T类型的元素(即想从列表中读取T类型的元素),则需要把这个列表声明成
<? extends T>。但这种情况下不能往该列表中添加任何元素,因为编译器无法确定具体的子类型。
- 消费者使用super:如果需要一个列表来存放T类型的元素(即想把T类型的元素加入到列表中),则需要把这个列表声明成
-
适用性不同:
- 下界
<? super T>:不影响往里存元素,但往外取元素时只能放在Object对象里。因此,经常往里插入元素的场景,适合用下界super。 - 上界
<? extends T>:不能往里存元素,只能往外取元素。因此,频繁往外读取内容的场景,适合用上界extends。
- 下界
示例说明
-
List<? extends Number>:- 不能添加元素:因为编译器无法确定具体的子类型,如Integer、Double等,所以无法安全地添加元素。
- 可以读取元素:读取出的元素可以安全地强制转换为Number类型或其子类型。
-
List<? super Integer>:- 可以添加元素:可以添加Integer类型或其子类型的元素,因为这些元素在编译期间可以安全地强制转换为Integer类型或其父类型。
- 不能读取特定类型的元素:只能将读取出的元素放在Object对象中,因为无法确定具体的类型。
综上所述,泛型中的通配符extends和super在含义、使用场景和适用性方面存在显著的差异。了解这些差异有助于编写更加灵活和安全的泛型代码。

被折叠的 条评论
为什么被折叠?



