Java泛型
泛型
泛型概述
Java泛型是Java语言中的一个重要特性,它提供了一种参数化类型的机制,可以使代码更加灵活、可重用,并增加类型安全性。通过使用泛型,我们可以在编译时指定类、接口和方法的参数类型,从而提高代码的可读性和可维护性。
泛型原理
Java泛型的原理基于类型擦除(Type Erasure)。在编译时,所有的泛型类型信息都会被擦除,编译器会将泛型类型转换为其原始类型(Raw Type)。这意味着在运行时,无法访问泛型类型的具体信息。
泛型的类型参数会被擦除并替换为其上限或Object类型。例如,List<String>
在运行时会被擦除为 List
或 List<Object>
。
泛型特性
Java泛型具有以下特性:
类型安全性:泛型提供了编译时的类型检查机制,可以在编译时检测类型错误,减少了运行时的异常风险。
代码重用:泛型可以实现类型无关的代码,提高了代码的重用性和灵活性。
避免类型转换:泛型可以避免手动进行类型转换,减少了代码中的冗余和错误的可能性。
泛型类
在Java中,我们可以使用泛型来定义泛型类。泛型类在类名后面使用尖括号 <T>
来指定类型参数,并在类的属性、方法或构造函数中使用这个类型参数。
下面是一个示例的泛型类的定义:
public class MyGenericClass<T> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
在上述示例中,MyGenericClass<T>
是一个泛型类,其中的 T
是类型参数。我们可以在类的方法中使用 T
来代表泛型类型,从而使该类可以适用于不同类型的数据。
泛型方法
除了泛型类,Java还支持泛型方法。泛型方法是指在方法声明中使用泛型类型参数的方法。
下面是一个示例的泛型方法的定义:
public class MyGenericMethod {
public <T> void printItem(T item) {
System.out.println("Item: " + item);
}
}
在上述示例中,printItem()
是一个泛型方法,其中的 <T>
表示类型参数。通过使用泛型方法,我们可以在调用方法时指定参数的类型,从而使方法可以适用于不同类型的参数。
通配符
通配符是泛型中的一个重要概念,用于表示未知类型。在Java泛型中,我们可以使用通配符来限制类型参数的范围。
?
:表示未知类型,可以用于表示任意类型。? extends T
:表示类型的上界限定,表示类型参数是 T 或 T 的子类。? super T
:表示类型的下界限定,表示类型参数是 T 或 T 的父类。
下面是一个示例,展示如何使用通配符:
public class GenericExample {
public void process(List<?> list) {
for (Object item : list) {
System.out.println("Item: " + item);
}
}
public void addItems(List<? super Integer> list) {
list.add(1);
list.add(2);
list.add(3);
}
public List<? extends Number> getNumbers() {
List<Integer> integers = new ArrayList<>();
integers.add(1);
integers.add(2);
integers.add(3);
return integers;
}
}
在上述示例中,process()
方法接收一个通配符类型的 List
,并对列表中的元素进行遍历打印。
addItems()
方法接收一个下界限定为 Integer
的 List
,并向列表中添加整数元素。
getNumbers()
方法返回一个上界限定为 Number
的列表,其中元素为整数。
类型擦除
Java泛型使用了类型擦除(Type Erasure)的机制。在编译时,泛型类型会被擦除,并替换为其上界或Object类型。这意味着在运行时无法获取泛型类型的具体信息。
例如,List<String>
在编译时会被擦除为 List
或 List<Object>
。
虽然在运行时无法获取泛型类型的具体信息,但在编译时仍然可以进行类型检查,以确保类型的安全性。
- 感谢你赐予我前进的力量