1、介绍
泛型可以参数化类型,在编写代码时可以定义带泛型的类或者方法,编译时使用具体的类型来替换。使用泛型可以在编译时检测出错误而不是在运行时检测出错误,这样可以使泛型代码向后兼容使用原始类型的遗留代码,也可以提高代码的可靠性和可读性。通常考虑对在类中要操作的引用数据类型不确定时使用泛型。
2、定义泛型类、接口和方法
泛型类
/** * 参数T可以为任意标识,最好使用常见的如T、E、K、V等形式的参数常用于表示泛型 * 在实例化泛型类时,必须指定T的具体类型 */ public class GenericClass<T> { /** * 泛型变量 */ private T var;public GenericClass(T var) { this.var = var; } /** * 泛型方法 * @return */ public T genericMethod() { return var; } }
GenericClass<Integer> genericClass = new GenericClass<Integer>(100); GenericClass<String> genericClass2 = new GenericClass<String>("kinson"); System.out.println(genericClass.getVar()); System.out.println(genericClass2.getVar());
泛型接口
public interface GenericInterface<T> { T study(); }
/** * 不传入具体的泛型参数类型,此时需要将泛型的声明加上 */ public class GenericStudy<T> implements GenericInterface<T> {
@Override
public T study() {
return (T)"Java";
}
}
/** * 传入具体的泛型参数类型,此时所有使用泛型的地方都需要改成传入的是参类型 */ public class JavaStudy implements GenericInterface<String> { @Override public String study() { return "Java"; } }
泛型方法
/** * 泛型方法 * * @param var * @param <T> * @return */ public <T> T show(T var) { return var; } public static <T> T print(GenericClass<T> genericClass) { return genericClass.getVar(); }
3、泛型通配符
有三种形式,分别是?、? extends T和? super T,其中T是泛型类型。第一个?是非受限统配,等效于? extends Object。第二个? extends T是受限通配,表示T或者是T的子类型。第三个? super T是下限通配,表示T或者T的父类型。在具体的使用过程中,可以为传入的泛型类型实参指定上下边界的限制,如? extends Number来限制为父类为Number类型。
4、注意点
- 泛型类型必须是引用类型,不能是int、double等基本类型
- 不能创建一个确切的泛型类型的数组。
- 在静态上下文中不允许累的参数是泛型类型
- 异常类不能是泛型的