泛型边界的使用
在 Java 中,泛型边界用于对泛型类型参数进行限制,确保泛型类型参数满足特定的条件。泛型边界可以分为上界和下界,下面分别进行详细介绍。
上界(Upper Bounds)
1. 概念
上界指定了泛型类型参数必须是某个特定类型或其子类型。使用 extends
关键字来定义上界,语法格式为 <T extends SomeClass>
或 <? extends SomeClass>
,这里的 SomeClass
可以是类或接口。
2. 类上使用上界
当在类的定义中使用泛型上界时,泛型类型参数必须是指定上界类型或其子类型。
示例代码:
// 定义一个泛型类,T 必须是 Number 或其子类
class Container<T extends Number> {
private T value;
public Container(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class UpperBoundClassExample {
public static void main(String[] args) {
// 可以使用 Integer 作为泛型类型参数,因为 Integer 是 Number 的子类
Container<Integer> intContainer = new Container<>(10);
System.out.println(intContainer.getValue());
// 编译错误,String 不是 Number 的子类
// Container<String> stringContainer = new Container<>("hello");
}
}
在上述代码中,Container
类的泛型类型参数 T
被限制为 Number
或其子类,因此可以使用 Integer
作为泛型类型参数,但不能使用 String
。
3. 方法上使用上界
在方法的定义中也可以使用泛型上界,这样可以对方法的泛型类型参数进行限制。
示例代码:
public class UpperBoundMethodExample {
// 定义一个泛型方法,T 必须是 Number 或其子类
public static <T extends Number> double sum(T a, T b) {
return a.doubleValue() + b.doubleValue();
}
public static void main(String[] args) {
// 可以使用 Double 作为泛型类型参数
double result = sum(1.5, 2.5);
System.out.println(result);
// 编译错误,String 不是 Number 的子类
// sum("hello", "world");
}
}
在上述代码中,sum
方法的泛型类型参数 T
被限制为 Number
或其子类,因此可以使用 Double
作为泛型类型参数,但不能使用 String
。
4. 通配符使用上界
在使用泛型通配符时,也可以指定上界,用于表示可以接受指定类型或其子类型的集合。
示例代码:
import java.util.ArrayList;
import java.util.List;
public class UpperBoundWildcardExample {
// 方法接受一个 List,其中元素类型必须是 Number 或其子类
public static void printList(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num);
}
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
// 可以传入 Integer 类型的 List
printList(intList);
List<Double> doubleList = new ArrayList<>();
doubleList.add(1.5);
doubleList.add(2.5);
// 可以传入 Double 类型的 List
printList(doubleList);
// 编译错误,List<String> 不符合上界要求
// List<String> stringList = new ArrayList<>();
// printList(stringList);
}
}
在上述代码中,printList
方法接受一个 List
,其中元素类型必须是 Number
或其子类,因此可以传入 Integer
类型或 Double
类型的 List
,但不能传入 String
类型的 List
。
下界(Lower Bounds)
1. 概念
下界指定了泛型类型参数必须是某个特定类型或其父类型。使用 super
关键字来定义下界,语法格式为 <? super SomeClass>
,这里的 SomeClass
可以是类或接口。
2. 通配符使用下界
下界通常用于泛型通配符,用于表示可以接受指定类型或其父类型的集合。
示例代码:
import java.util.ArrayList;
import java.util.List;
public class LowerBoundWildcardExample {
// 方法接受一个 List,其中元素类型必须是 Integer 或其父类
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 5; i++) {
list.add(i);
}
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
// 可以传入 Integer 类型的 List
addNumbers(intList);
System.out.println(intList);
List<Number> numberList = new ArrayList<>();
// 可以传入 Number 类型的 List
addNumbers(numberList);
System.out.println(numberList);
// 编译错误,List<Double> 不符合下界要求
// List<Double> doubleList = new ArrayList<>();
// addNumbers(doubleList);
}
}
在上述代码中,addNumbers
方法接受一个 List
,其中元素类型必须是 Integer
或其父类,因此可以传入 Integer
类型或 Number
类型的 List
,但不能传入 Double
类型的 List
。
总结
- 上界
extends
用于限制泛型类型参数为某个类型或其子类型,常用于获取数据的场景。 - 下界
super
用于限制泛型类型参数为某个类型或其父类型,常用于添加数据的场景。
通过使用泛型边界,可以提高代码的类型安全性和可重用性。