基本概念
泛型的本质是个参数化的类型,将参数的类型作为一个参数,在运行时决定(?)。
在没有泛型之前,容器返回的类型都是Object类型,因此根据实际情况,降返回值强转为期望的类型。引入泛型之后,容器中的存储类型在声明时就可以确定,因此对容器的操作不需要进行类型转换。
使用泛型一方面可以增加代码的可读性,降低程序出错的可能性,也提高了程序的运行效率。
ArrayList list = new ArrayList();
list.add('a');
Integer object = (Integer)list.get(0); //抛出强制类型转换异常
List<String> list = new ArrayList<String>();
list.add(1); //编译不通过,提早发现问题
list.add("1");
泛型的功能:
- 避免代码中的类型强转
- 限定类型。在编译时提供额外的类型检查,避免错误的值被存入容器
泛型分类
- 泛型接口
- 泛型类
- 泛型方法
有界泛型
- ?表示通配符类型,用于表达任意类型,但并不是object
- extends 定义上界
T extends UpperBound
T必须是UpperBound,或者其子类。
- super定义泛型的下界
T super LowerBound
T必须为LowerBound或者其父类。
复杂泛型
类型擦除
在编码阶段采用泛型加上的类型参数,会被编译器在编译时去掉,这个过程被称为类型擦除。因此,泛型主要用于编译阶段。编译后生成的Java字节码文件不包含泛型中的类型信息。由泛型附加的类型信息对JVM来说是不可见的。
通过反射,无法获取泛型的确定类型。