Java泛型详解
Java泛型(Generics)是一种强大的编程工具,使得代码可以在编译时进行类型检查,并提供更高的代码重用性和安全性。泛型允许定义类、接口和方法时,可以对其操作的数据类型进行参数化,从而使得这些类、接口和方法能适用于多种数据类型。
为什么使用泛型?
1. **类型安全**:在编译时检测类型错误,减少运行时异常。
2. **代码重用**:编写一次代码,可以应用于多种数据类型。
3. **可读性和可维护性**:通过泛型,可以明确表达意图,使代码更易理解和维护。
泛型语法
泛型使用尖括号 `<>` 来定义类型参数,例如 `List<T>` 中的 `T`。
泛型类
一个泛型类是带有一个或多个类型参数的类。例如:
```java public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return this.t; } } ```
可以像这样使用这个泛型类:
```java public class Main { public static void main(String[] args) { Box<Integer> integerBox = new Box<>(); integerBox.set(10); System.out.println("Integer Value: " + integerBox.get()); Box<String> stringBox = new Box<>(); stringBox.set("Hello"); System.out.println("String Value: " + stringBox.get()); } } ```
泛型方法
泛型方法是在声明方法时引入一个或多个类型参数。这些类型参数放置在方法的返回类型之前。例如:
```java public class GenericMethodExample { // 泛型方法 printArray public static <E> void printArray(E[] inputArray) { for (E element : inputArray) { System.out.printf("%s ", element); } System.out.println(); } public static void main(String[] args) { Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.print("Array of Integers: "); printArray(intArray); System.out.print("Array of Doubles: "); printArray(doubleArray); System.out.print("Array of Characters: "); printArray(charArray); } } ```
泛型接口
泛型也可以应用于接口。例如:
```java public interface Pair<K, V> { public K getKey(); public V getValue(); } public class OrderedPair<K, V> implements Pair<K, V> { private K key; private V value; public OrderedPair(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 OrderedPair<>("One", 1); System.out.println("Key: " + pair.getKey() + ", Value: " + pair.getValue()); } } ```
有界类型参数
可以通过`extends`关键字来限制类型参数。例如,限制类型参数必须是某个类的子类或实现某个接口:
```java public class Util { public static <T extends Comparable<T>> int compare(T t1, T t2) { return t1.compareTo(t2); } } public class Main { public static void main(String[] args) { System.out.println(Util.compare(10, 20)); // 输出负数,因为10小于20 } } ```
通配符
通配符是另一种泛型机制,用于灵活地指定类型。例如:
无界通配符
表示任何类型:
```java public static void printList(List<?> list) { for (Object elem : list) System.out.print(elem + " "); System.out.println(); } ```
有界通配符
上界通配符:`<? extends T>` 表示类型是T或T的子类型。
```java public void processElements(List<? extends Number> list) { for (Number num : list) { System.out.println(num.doubleValue()); } } ```
下界通配符:`<? super T>` 表示类型是T或T的父类型。
```java public void addNumbers(List<? super Integer> list) { list.add(10); list.add(20); } ```
类型擦除
泛型在编译时会进行类型擦除,以确保与非泛型代码的兼容性。这意味着所有类型参数都会被擦除,替换为其限定类型(无限定时为Object)。例如:
```java public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } } ```
在编译后实际上类似于:
```java public class Box { private Object t; public void set(Object t) { this.t = t; } public Object get() { return t; } } ```
总结
Java泛型是一个重要且强大的特性,能够提高代码的类型安全性、可重用性和可读性。通过泛型类、泛型方法、泛型接口、有界类型参数和通配符等机制,开发者可以编写更加健壮和灵活的代码。理解和掌握泛型的使用,对于编写高质量的Java程序至关重要。