1.什么是泛型
泛型,即“参数化类型” 。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。参数化类型,就是将类型由原来的具体的类型参数化,类似于方法中的 变量参数,此时类型也定义成参数形式,然后在使用或者调用时传入具体的类型。
ArrayList<String> list = new ArrayList<String>();//尖括号中String即为类型
在上面的示例中,我们创建了一个ArrayList
,它只能存储String
类型的元素。当我们尝试将其他类型的对象添加到这个列表时,编译器会发出警告或错误。
2.泛型类
泛型类是具有一个或多个类型参数的类。这些类型参数可以在类的实例化时被指定为具体的数据类型。通过使用泛型类,我们可以创建更加通用和类型安全的数据结构。
public class Box<T> {
private T data;
public void setData(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
在上面的示例中,Box<T>
是一个泛型类,T
是一个类型参数。它可以用来存储任何类型的对象。
3.泛型方法
除了泛型类外,Java还支持泛型方法,它可以在方法中使用类型参数。
public <T> T method(T[] array) {
return array[0];
}
在上面的示例中,Method是一个泛型方法,它接受一个泛型数组并返回数组的第一个元素。
4.通配符
Java中的通配符用?表示,它表示未知类型。通配符可以用来表示某个泛型类型的父类或子类,从而实现灵活的类型匹配。
public void printList(List<?> list) {
for (Object obj : list) {
System.out.println(obj);
}
}
在上面的示例中,printList
方法接受任何类型的List
作为参数。
5.类型擦除
泛型是Java 1.5版本才引进的概念,在这之前是没有泛型的,但是,泛型代码能够很好地和之前版本的代码兼容。那是因为,泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,我们称之为一类型擦除。 泛型类被类型擦除后,相应的类型就被替换成 Object 类型或者上限类。
ArrayList<String> list = new ArrayList<String>();
ArrayList<Integer> anotherList = new ArrayList<Integer>();
System.out.println(list.getClass() == anotherList.getClass()); // true
在上面的示例中,尽管list
和anotherList
存储的是不同类型的对象,但它们的类对象是相同的,因为泛型信息在运行时被擦除了。