泛型中的 extends
和 super
关键字用于设置类型参数的上下界,控制可以传递给泛型类型的参数类型。它们的区别在于限制的方向和用途:
1.extends:
- 上界限制: 使用
extends
关键字定义了一个类型参数的上界,意味着传入的类型必须是指定类型或其子类型。 - 读取操作: 当泛型参数有上界限制时,允许进行读取(get)操作,因为可以确保所有对象至少有指定类型的方法和属性。
- 写入限制: 由于Java的类型擦除和安全性考虑,如果有上界限制,直接添加对象到集合可能会受到限制(特别是当使用非具体类型如
? extends T
时)。 - 示例:
List<? extends Number>
可以接受 List<Integer>
或 List<Double>
等,但你不能直接向这样的列表中添加元素,除了 null
,因为编译器无法确定确切的类型。
2.super:
- 下界限制: 使用
super
关键字定义了一个类型参数的下界,意味着传入的类型必须是指定类型或其父类型。 - 写入操作: 允许写入(put)操作,因为你总是可以向上转型为基类,所以可以安全地添加基类及其子类的实例。
- 读取限制: 读取时可能需要类型转换,因为集合中可能包含
- 示例:
List<? super Number>
可以接受 List<Number>
、List<Object>
或任何Number的父类的List,你可以向这样的列表中添加 Number
或其任何子类的实例。
总结来说,extends
通常用于确保可以安全地使用对象的特性(即读取),而 super
用于确保可以安全地插入对象(即写入)。在实际应用中,根据你需要执行的操作(读或写)来决定使用哪一个。