在 Java 中,泛型是一种强类型检查机制,它允许我们在编译时期指定类、接口或方法的参数和返回值类型。使用泛型可以实现代码的重用性、类型安全性和提高代码的可读性。
下面是关于 Java 泛型的一些重要概念和用法:
- 泛型类(Generic Class):通过在类名后面使用尖括号
<T>
来声明一个泛型类,在类内部可以使用类型参数T
来表示一种未知的类型。例如:List<T>
表示一个泛型类,可以存储任意类型的元素。 - 泛型接口(Generic Interface):与泛型类类似,可以使用类型参数来声明泛型接口。例如:
Comparable<T>
是一个泛型接口,定义了比较两个对象的方法。 - 泛型方法(Generic Method):在方法的返回类型前使用
<T>
来声明一个泛型方法,使得方法能够使用类型参数来表示一种未知的类型。例如:<T> T get(int index)
是一个泛型方法,根据传入的索引返回相应类型的元素。 - 类型通配符(Wildcard):使用
?
作为通配符来表示未知类型,可以用在泛型类、泛型接口和泛型方法中。例如:List<?>
表示一个未知具体类型的列表。 - 上界通配符(Upper Bounded Wildcard):使用
<? extends 类型>
来限定泛型的上界,表示传入的泛型类型是给定类型或其子类。例如:List<? extends Number>
表示一个元素类型是 Number 或其子类的列表。 - 下界通配符(Lower Bounded Wildcard):使用
<? super 类型>
来限定泛型的下界,表示传入的泛型类型是给定类型或其父类。例如:List<? super Integer>
表示一个元素类型是 Integer 或其父类的列表。
通过使用泛型,我们可以创建更灵活、安全和可读性高的代码。它们使得我们可以在编译时期进行类型检查,并减少了强制类型转换的需要。
泛型方法:
泛型方法是指在方法定义中使用了一个或多个类型参数的方法。通过使用泛型方法,可以在方法调用时灵活地指定不同的参数类型,从而提高代码的重用性和灵活性。
下面是关于泛型方法的一些重要概念和用法:
- 泛型方法的声明:在方法的返回类型前使用
<T>
来声明一个泛型方法,其中<T>
表示一种未知的类型。例如:public <T> T methodName(T arg)
定义了一个泛型方法methodName
,参数和返回值都是类型为T
的。 - 类型推断:当调用泛型方法时,可以根据方法参数的类型自动推断出类型参数。例如:
methodName("Hello")
,编译器会根据传入的参数类型(如字符串)推断出类型参数T
为String
。 - 多个类型参数:泛型方法可以使用多个类型参数,并以逗号分隔。例如:
public <T, U> void methodName(T arg1, U arg2)
定义了一个同时使用两个类型参数的泛型方法。 - 类型限定:可以对泛型方法的类型参数设置限定,使用
extends
关键字限定类型参数必须是指定类或其子类。例如:public <T extends Number> void methodName(T arg)
表示类型参数T
必须是Number
类或其子类。
下面是一个示例泛型方法的定义:
public <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
在上面的示例中,<T>
表示该方法为泛型方法,并引入了类型参数 T
。方法的参数 array
是一个类型为 T
的数组。通过使用泛型方法,我们可以在调用时传递不同类型的数组,实现打印不同类型数组内容的灵活性。
例如:
Integer[] intArray = {1, 2, 3, 4, 5};
String[] strArray = {"Hello", "World"};
printArray(intArray); // 调用泛型方法,打印整数数组
printArray(strArray); // 调用泛型方法,打印字符串数组
在上面的示例中,通过调用 printArray
泛型方法,我们可以打印不同类型的数组,而不需要编写多个针对不同类型的方法。