在 Java 中,泛型(Generics)是一种在编译时进行类型安全检查的机制,它允许你在定义类、接口和方法时使用类型参数,从而提高代码的安全性和可重用性。
一、泛型的作用
1.类型安全
在使用泛型之前,集合类(如ArrayList
、LinkedList
等)可以存储任意类型的对象。这可能导致在运行时出现类型转换错误,因为在从集合中取出元素时,需要进行显式的类型转换。使用泛型后,编译器可以在编译时进行类型检查,确保只存储特定类型的对象,从而避免了运行时的类型转换错误。
2.代码重用
通过使用泛型,可以编写适用于多种不同类型的通用代码,而不需要为每种类型都编写重复的代码。例如,可以定义一个泛型方法来对两个参数进行比较,而不管参数的具体类型是什么。
二、泛型的基本语法
1.定义泛型类和接口
在定义类或接口时,可以使用类型参数来表示未知的类型。类型参数通常用大写字母表示,例如T
、E
、K
、V
等。
范型方法定义格式:修饰符 <类型> 返回值类型 方法名(类型 变量名) { }
范型接口定义格式:修饰符 interface 接口名<类型> { }
public class Box<T> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
2.定义泛型方法
泛型方法可以在普通类或泛型类中定义。泛型方法在返回类型前面使用类型参数列表来声明类型参数。
public class Util {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
}
三、泛型的类型限定
1.类型通配符: <?>
ArrayList<?>: 表示元素类型未知的ArrayList,它的元素可以匹配任何的类型
但是并不能把元素添加到ArrayList中了,获取出来的也是父类类型
2.类型通配符上界限定: <? extends 类型>
使用extends
关键字来指定类型参数的上界,表示类型参数必须是指定类型或其子类型。
public class Util {
public static <T extends Number> double sum(T[] array) {
double sum = 0;
for (T element : array) {
sum += element.doubleValue();
}
return sum;
}
}
2.类型通配符下界限定:<? super 类型>
使用super
关键字来指定类型参数的下界,表示类型参数必须是指定类型或其父类型。
public class Util {
public static <T> void printObjects(T[] array, T lowerBound) {
for (T element : array) {
if (element instanceof Comparable && ((Comparable<T>) element).compareTo(lowerBound) >= 0) {
System.out.print(element + " ");
}
}
System.out.println();
}
}