在 Java 泛型中,extends
和 super
是用于通配符类型的关键字,用于限制泛型类型参数的上界和下界。它们在泛型方法和类中起到了非常重要的作用,帮助实现类型安全和灵活的代码。
extends
关键字
用法
extends
用于指定类型参数的上界,即泛型类型参数必须是指定类的子类或实现类。
语法
class GenericClass<T extends Number> {
// 类定义
}
void method(List<? extends Number> list) {
// 方法定义
}
示例
class Box<T extends Number> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.set(10);
System.out.println(intBox.get());
Box<Double> doubleBox = new Box<>();
doubleBox.set(10.5);
System.out.println(doubleBox.get());
}
}
在这个示例中,Box
类的类型参数 T
必须是 Number
的子类。因此,可以用 Integer
和 Double
来实例化 Box
。
super
关键字
用法
super
用于指定类型参数的下界,即泛型类型参数必须是指定类的父类或超类。
语法
void method(List<? super Integer> list) {
// 方法定义
}
示例
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
for (Object obj : list) {
System.out.println(obj);
}
}
}
在这个示例中,list
可以是 Integer
的任何父类的列表。super
关键字通常用于消费数据的场景,即从泛型集合中读取数据。
PECS 原则
extends
和 super
的使用通常遵循 PECS 原则:
- Producer Extends: 如果需要一个只读的泛型集合(生产者),使用
extends
。 - Consumer Super: 如果需要一个只写的泛型集合(消费者),使用
super
。
示例
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> intList = List.of(1, 2, 3);
printNumbers(intList);
List<Number> numList = List.of(1, 2.0, 3);
addNumbers(numList);
}
// Producer Extends
public static void printNumbers(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num);
}
}
// Consumer Super
public static void addNumbers(List<? super Integer> list) {
list.add(4); // 可以添加Integer
}
}
在 printNumbers
方法中,我们使用 extends
关键字,因为我们只从列表中读取数据。在 addNumbers
方法中,我们使用 super
关键字,因为我们只向列表中添加数据。
详细解释
extends
- 上界通配符:使用
? extends T
,表示可以接受类型T
或其子类。 - 适用场景:通常用于只读操作。例如,从一个集合中读取数据。
super
- 下界通配符:使用
? super T
,表示可以接受类型T
或其父类。 - 适用场景:通常用于写操作。例如,向一个集合中添加数据。
总结
extends
:用于指定类型参数的上界,通常用于生产者(只读)的场景。super
:用于指定类型参数的下界,通常用于消费者(只写)的场景。- PECS 原则:Producer Extends, Consumer Super,指导何时使用
extends
和super
。
通过理解和正确使用 extends
和 super
,可以编写出类型安全且灵活的泛型代码,满足各种不同的需求。