在Java中,泛型(Generics)提供了一种方式来编写具有类型安全性的代码,同时保持代码的灵活性。泛型上限(Upper Bound)和下限(Lower Bound)是泛型类型参数的两种约束,它们允许你限制泛型类型参数可以被哪些类型实例化。
泛型上限(Upper Bound)
上限是指定泛型类型参数可以扩展的类型。这意味着泛型类型参数必须是指定类或接口的子类型。
public class MyClass<T extends Number> {
private T data;
public MyClass(T data) {
this.data = data;
}
public void printData() {
System.out.println(data);
}
}
// 使用上限
MyClass<Integer> myClass = new MyClass<>(123);
在这个例子中,MyClass<T extends Number>
定义了一个上限为 Number
的泛型类型参数 T
。这意味着 T
可以是 Integer
、Double
、Float
等 Number
类型的子类型。
泛型下限(Lower Bound)
下限是指定泛型类型参数可以是哪些类型的超类型。这意味着泛型类型参数必须是指定类或接口的超类型。
public class MyClass<T super String> {
private T data;
public MyClass(T data) {
this.data = data;
}
public void printData() {
System.out.println(data);
}
}
// 使用下限
MyClass<String> myClass = new MyClass<>("Hello");
在这个例子中,MyClass<T super String>
定义了一个下限为 String
的泛型类型参数 T
。这意味着 T
可以是 String
类型或其超类型,但实际上在Java中,你通常不会定义泛型的下限,因为Java不支持协变和逆变。
通配符(Wildcards)
在泛型的上下文中,通配符 ?
也可以用来指定上限或下限。
? extends X
表示上限为X
。? super X
表示下限为X
。
泛型边界的限制
在Java中,泛型边界有一些限制:
- 泛型类型参数不能直接使用基本数据类型。
- 泛型类型参数不能直接使用
void
类型。 - 泛型类型参数不能直接使用数组类型。
泛型边界的应用
泛型边界在集合类中非常有用,例如 List<? extends Number>
可以用来接收任何 Number
类型或其子类型的列表。
总结
泛型上限和下限为Java泛型提供了灵活性和类型安全性。通过使用边界,你可以确保泛型类型参数符合特定的类型约束,从而编写更安全、更可靠的代码。