为什么要有泛型 (Generic)
泛型: 标签
举例:
中药店,每个抽屉外面贴着标签
超市购物架上很多瓶子,每个瓶子装的是什么,有标签
泛型的设计背景
集合容器类在设计阶段 / 声明阶段不能确定这个容器到底实际存的是什么类型的
对象,所以 在 JDK1.5 之前只能把元素类型设计为 Object , JDK1.5 之后使用泛型来
解决。 因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于
这个元素如何保存,如何管理等是确定的,因此此时 把元素的类型设计成一个
参数,这个类型参数叫做泛型。 Collection<E> , List<E> , ArrayList<E> 这个 <E> 就
是类型参数,即泛型。
在集合中使用泛型
1. 泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:
<E1,E2,E3>
2. 泛型类的构造器如下: public GenericClass(){} 。
而下面是错误的: public GenericClass<E>(){}
3. 实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致。
4. 泛型不同的引用不能相互赋值。
> 尽管在编译时 ArrayList<String> 和 ArrayList<Integer> 是两种类型,但是,在运行时只有
一个 ArrayList 被加载到 JVM 中。
5. 泛型如果不指定,将被擦除,泛型对应的类型均按照 Object 处理,但不等价
于 Object 。 经验: 泛型要使用一路都用。要不用,一路都不要用。
6. 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
7. jdk1.7 ,泛型的简化操作: ArrayList<Fruit> flist = new ArrayList<>();
8. 泛型的指定中不能使用基本数据类型,可以使用包装类替换
9. 在类 / 接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态 属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在 静态方法 中不能使用类的泛型。
10. 异常类不能是泛型的
11. 不能使用 new E[] 。但是可以: E[] elements = (E[])new Object[capacity];
参考: ArrayList 源码中声明: Object[] elementData ,而非泛型参数类型数组。
12. 父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型:
子类不保留父类的泛型:按需实现
没有类型 擦除
具体类型
子类保留父类的泛型:泛型子类
全部保留
部分保留
结论:子类必须是“富二代”,子类除了指定或保留父类的泛型,还可以增加自
己的泛型
泛型在继承上的体现