Java 泛型是 Java 编程语言的一项功能,它允许程序员在编译时定义方法和类的类型参数,而不是在运行时。这样做的好处是可以提高代码的类型安全性和重用性,同时还能够在一定程度上减少代码量。
在 Java 中,泛型通常是通过使用类型参数(例如,`E`、`T`、`K` 和 `V` 等)来表示。这些类型参数可以在编译时被指定为任何类型,而在运行时则被擦除,也就是说,泛型类型在编译时会被转换为它们的实际类型。这种机制称为类型擦除。
类型擦除是指在编译期间,所有的泛型信息都会被移除,因此在运行时无法知道泛型的具体类型。这意味着泛型只在编译时起作用,运行时所有的泛型类都被转换为原始类型(raw types),如 `List<E>` 会被擦除为 `List`。由于类型信息不再存在,所以泛型只在编译时期起作用。
使用泛型的好处包括:
- **类型安全:** 泛型可以捕获编译时错误,避免运行时错误。
- **代码重用:** 泛型可以编写可重用的代码,适用于不同的数据类型。
- **类型抽象:** 泛型可以隐藏底层数据类型,使代码更加抽象和模块化。
泛型的一些常用关键字包括 `extends` 和 `super`。`extends` 关键字用于指定一个上限,而 `super` 关键字用于指定一个下限。
例如,我们可以定义一个泛型类:
```java
// Java 泛型示例:定义一个带有泛型的类
public class Box<T> { // T 是一个类型参数
private T t; // 声明 T 类型的变量
public void set(T t) { // 设置 t 的值
this.t = t;
}
public T get() { // 获取 t 的值
return t;
}
}
// 使用泛型的方法
public <U> U getU(U u) { // 此方法返回类型 U
return u; // 返回传递给方法的 U 类型的对象
}
// 使用泛型接口
interface Generator<T> { // 这是一个泛型接口
T next(); // 返回下一个 T 类型的值
}
// 实现泛型接口
class IntegerGenerator implements Generator<Integer> {
public Integer next() { // 实现 next 方法
return new Integer(0); // 返回一个整数
}
}
// 使用泛型类和方法的示例
public class Main {
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>(); // 创建一个 Box 实例来存储 Integer 类型
integerBox.set(new Integer(10)); // 设置 Box 的值
System.out.println(integerBox.get()); // 获取并打印 Box 的值
// 使用泛型方法
System.out.println(getU(new Integer(10))); // 输出:10
// 使用泛型接口
Generator<Integer> integerGenerator = new IntegerGenerator(); // 创建一个 IntegerGenerator 实例
System.out.println(integerGenerator.next()); // 输出:0
}
}