概述
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
泛型只在编译阶段有效。
类型擦除
Java是因为 Java 在编译期间,所有的泛型信息都会被擦掉,这也就是通常所说类型擦除 。
List<Integer> list = new ArrayList<>();list.add(12);//这里直接添加会报错list.add("a");Class<? extends List> clazz = list.getClass();Method add = clazz.getDeclaredMethod("add", Object.class);//但是通过反射添加,是可以的add.invoke(list, "kl");System.out.println(list);
常用的通配符
- ? 表示不确定的 java 类型
- T (type) 表示具体的一个 java 类型
- K V (key value) 分别代表 java 键值中的 Key Value
-
三种使用方式
泛型类
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型//在实例化泛型类时,必须指定T的具体类型public class Generic<T> {private T key;public Generic(T key) {this.key = key;}public T getKey() {return key;}}
如何实例化泛型类:
Generic<Integer> genericInteger = new Generic<Integer>(123456);
泛型接口
public interface Generator<T> {public T method();}
实现泛型接口,不指定类型:
class GeneratorImpl<T> implements Generator<T>{@Overridepublic T method() {return null;}}
实现泛型接口,指定类型:
class GeneratorImpl implements Generator<String>{@Overridepublic String method() {return "hello";}}
泛型方法
public static <E> void printArray(E[] inputArray) {for (E element : inputArray) {System.out.printf("%s ", element);}System.out.println();}
使用:
// 创建不同类型数组: Integer, Double 和 CharacterInteger[] intArray = { 1, 2, 3 };String[] stringArray = { "Hello", "World" };printArray(intArray);printArray(stringArray);
