Java中的泛型(Generics)是JDK 5.0引入的一个新特性,它提供了编译时类型安全,允许在定义类、接口和方法时使用类型参数(type parameters)。泛型的主要目的是在编译时增强类型检查,以减少运行时类型转换的错误,同时保持使用泛型类型时的类型灵活性。
以下是Java中泛型工作的几个关键点:
- 类型参数:
泛型类、接口和方法使用尖括号<>
中的类型参数进行定义。例如,ArrayList<E>
是一个泛型类,其中E
是一个类型参数,代表元素类型。public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } }
在上面的例子中,
Box<T>
是一个泛型类,其中T
是一个类型参数,可以用来代表任何类型。 - 类型推断:
在创建泛型对象或调用泛型方法时,编译器通常可以通过上下文推断出类型参数的具体类型,这称为类型推断。如果编译器无法推断出类型,就需要显式地提供类型参数。Box<Integer> integerBox = new Box<>(); // 类型推断为Integer Box<String> stringBox = new Box<String>(); // 显式指定类型参数
-
类型擦除:
泛型信息在编译后会被擦除,这称为类型擦除。编译器会将泛型类型转换为原始类型(raw type),并在必要时插入类型转换和类型检查代码。这意味着运行时并没有泛型类型的概念,所有的类型参数都会被替换为它们的边界或者是Object。因此,泛型并不能提供运行时的类型安全,而主要是在编译时提供类型检查。 -
泛型限制与边界:
可以通过extends
关键字为泛型类型参数设置上界,以确保类型参数只能是某种类型的子类或实现类。public class NumberBox<T extends Number> { private T t; // ... }
在这个例子中,
NumberBox
的类型参数T
必须是Number
类或其子类的实例。 - 泛型方法与泛型类:
泛型方法不仅可以在泛型类中出现,也可以在普通类中定义。泛型方法使用类型参数来定义返回类型或参数类型。public class Util { public static <T> T getFirst(T[] array) { if (array != null && array.length > 0) { return array[0]; } else { return null; } } }
在这个例子中,
getFirst
是一个泛型方法,它接受一个泛型数组并返回数组的第一个元素。 - 通配符:
泛型通配符(?
)用于表示未知类型,常用于泛型方法的参数和泛型类的字段中。通配符有三种形式:无界通配符(?
)、上界通配符(? extends Type
)和下界通配符(? super Type
),它们提供了更灵活的类型匹配。
泛型极大地增强了Java的类型系统,使得代码更加清晰、可读和可维护,同时减少了因类型转换导致的运行时错误。然而,由于类型擦除的存在,泛型并不能完全替代传统的对象封装和转换机制。在使用泛型时,还需要注意一些与类型擦除相关的潜在问题,如桥接方法的生成和原始类型的兼容性问题。
标签:Box,Java,通配符,如何,参数,类型,泛型,public From: https://blog.csdn.net/meishengjie111/article/details/136774878