参数化类型是一种在类、接口或方法中使用的类型,它可以接受一个或多个类型参数。例如,List 是一个参数化类型,表示一个元素类型为字符串的列表。
泛型类是具有一个或多个类型参数的类。类型参数可以在类的声明中使用,并在类的实例化时指定具体的类型。例如:
public class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
在上面的例子中,Box 是一个泛型类,T 是类型参数。在创建 Box 类的实例时,可以指定具体的类型,例如 Box 或 Box。
泛型方法是具有一个或多个类型参数的方法。类型参数可以在方法的返回类型之前声明,并在方法调用时指定具体的类型。例如:
public <T> T getObject(T[] array, int index) {
return array[index];
}
在上面的例子中, 是类型参数,getObject 方法返回数组中指定索引的元素,且返回类型与数组元素类型相同。
通配符类型是一种特殊的泛型类型,用于表示不确定的类型。通配符类型有三种形式:>、 extends T> 和 super T>。参考
【JAVA】泛型,泛型变量,通配符 <?> ,原理及应用详解
【JAVA】 ? super T 和 ? extends T的区别
例如:
> 表示任意类型。
extends T> 表示某个类的子类。
super T> 表示某个类的父类。
通配符类型通常用于方法参数或返回类型中,以提高灵活性。
Java 泛型通过类型擦除实现,在编译时会将泛型类型转换为原始类型。这意味着在运行时,泛型类型的信息会被擦除,而泛型参数会被替换为其边界类型或 Object 类型。例如,List 在运行时会被擦除为 List,而 T 会被替换为 Object。
这样做是为了确保泛型代码在运行时能够与之前的非泛型代码兼容,因为 Java 虚拟机(JVM)是在泛型被引入之前就存在的。
例如,考虑以下泛型类的定义:
public class Box<T> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
在类型擦除之后,编译器会将泛型类型 T 擦除为其边界类型或 Object 类型。因此,上述泛型类的擦除版本可能如下所示:
public class Box {
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
类型擦除的结果是,尽管在源代码中使用了泛型类型 T,但在编译后的字节码中,泛型类型信息会被擦除,使得所有类型参数都被替换为它们的擦除类型。这意味着在运行时,不再有关于泛型类型的具体信息可用,这种信息已经在编译时被擦除了。
尽管类型擦除在一定程度上降低了泛型的灵活性,但它确保了与之前版本的兼容性,并且使得泛型代码能够在不同版本的 Java 中正常运行。
Java 泛型支持自动装箱和拆箱,即自动将基本数据类型转换为相应的包装类(装箱),以及自动将包装类转换为基本数据类型(拆箱)。例如,自动装箱可以将 int 转换为 Integer,而自动拆箱可以将 Integer 转换为 int。主要有以下两个作用:
valueOf() 和 xxxValue() 等转换方法,而是可以直接赋值或使用对象,编写更加简洁清晰的代码。Java 泛型提供了一种强大的编程机制,可以提高代码的类型安全性、重用性和可读性。它允许开发人员编写通用的代码,以处理各种类型的数据,同时保持代码的简洁和清晰。