📌 目录
- 什么是泛型?
- 泛型的优势
- 泛型的基本语法
- 泛型类
- 泛型方法
- 通配符 (Wildcard) 使用
- 6.1
? extends T
- 6.2
? super T
- 6.3
?
- 6.1
- 泛型的边界
- 泛型的类型推断
- 总结
- 参考资料
- 出站链接
1. 什么是泛型?
Java 泛型是 Java 编程语言的一种机制,允许在类、接口和方法中定义类型参数,从而使得代码在处理不同类型的数据时更加灵活和安全。泛型使得编译器能够提供更强的类型检查,并且减少了类型转换的需要。泛型是 Java 5 引入的,常用于集合框架中。
通过使用泛型,Java 程序可以更加灵活地处理不同类型的对象,同时保证类型安全,从而避免类型转换错误。
2. 泛型的优势
- 类型安全:通过泛型,我们可以确保代码在编译时进行类型检查,从而避免在运行时出现类型转换错误。
- 代码复用:泛型可以在编写代码时不指定具体的数据类型,从而让代码适用于多种类型,增强了代码的复用性。
- 避免强制类型转换:泛型使得我们不再需要在使用集合时进行类型转换,减少了显式转换的错误风险。
3. 泛型的基本语法
泛型的基本语法通过使用尖括号 <>
来定义类型参数。
示例:
// 定义一个泛型类
class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>(); // 使用 Integer 类型
intBox.setValue(10);
System.out.println(intBox.getValue());
Box<String> strBox = new Box<>(); // 使用 String 类型
strBox.setValue("Hello");
System.out.println(strBox.getValue());
}
}
在这个例子中,Box
是一个泛型类,T
是一个类型参数。我们可以在使用 Box
类时指定类型(如 Integer
或 String
)。
4. 泛型类
泛型类是指类在定义时通过类型参数化,以便该类可以操作不同类型的数据。类型参数通常在类名后通过尖括号 <>
定义。
示例:
class Pair<K, V> { // K 和 V 是类型参数
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
public class Main {
public static void main(String[] args) {
Pair<String, Integer> pair = new Pair<>("age", 30);
System.out.println(pair.getKey() + ": " + pair.getValue());
}
}
在此示例中,Pair
是一个泛型类,其中 K
和 V
是类型参数。我们可以指定不同的数据类型作为键和值。
5. 泛型方法
泛型方法是在方法声明中定义类型参数。即使方法位于非泛型类中,也可以是泛型方法。
示例:
public class GenericMethod {
// 泛型方法
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3};
String[] strArray = {"A", "B", "C"};
printArray(intArray); // 打印 Integer 数组
printArray(strArray); // 打印 String 数组
}
}
在此示例中,printArray
是一个泛型方法,它能够接收任何类型的数组并打印其中的元素。
6. 通配符 (Wildcard) 使用
Java 泛型还支持通配符(wildcard),即 ?
,它用于表示未知类型。通配符在某些情况下非常有用,特别是当我们希望编写一个方法,可以处理不同类型的泛型参数。
6.1 ? extends T
- 用于表示上限通配符,意味着类型可以是
T
或其子类型。
public static void printNumbers(List<? extends Number> list) {
for (Number number : list) {
System.out.println(number);
}
}
在这个例子中,? extends Number
表示可以传入 Number
类及其任何子类的 List
。
6.2 ? super T
- 用于表示下限通配符,意味着类型可以是
T
或其父类型。
public static void addNumbers(List<? super Integer> list) {
list.add(10); // 可以添加 Integer 类型或其父类类型
}
在这个例子中,? super Integer
表示可以传入 Integer
类及其任何父类的 List
。
6.3 ?
?
表示一个未知类型,通常用于方法的参数中,不关心具体类型。
public static void printList(List<?> list) {
for (Object obj : list) {
System.out.println(obj);
}
}
7. 泛型的边界
Java 泛型允许定义类型的边界。通过设置上限或下限来限制泛型的类型范围。
上限:
public static <T extends Number> void printNumber(T number) {
System.out.println(number);
}
这表示 T
必须是 Number
或其子类。
下限:
public static <T super Integer> void addInteger(T obj) {
// 只允许传入 Integer 或其父类类型
}
8. 泛型的类型推断
Java 编译器支持在调用泛型方法时根据传入参数自动推断出泛型类型。通过类型推断,可以简化代码,避免显式指定泛型类型。
示例:
public class GenericTypeInference {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3};
printArray(intArray); // Java 会自动推断出 T 为 Integer 类型
}
}
9. 总结
- Java 泛型提供了强大的类型安全和灵活性,它允许我们定义可以操作多种类型数据的类和方法。
- 泛型有助于提高代码的重用性,同时减少类型转换错误。
- 泛型类、泛型方法和通配符(wildcard)使得 Java 能够更加通用地处理不同类型的对象。
- 泛型的边界和类型推断机制使得泛型功能更加灵活,可以定义更复杂的泛型约束。
发表回复