泛型可以看做普通类的工厂
泛型的好处
- 解决强制类型转换
- 避免插入错误类型的对象
类型变量的限定
<T extends BoudingType >
表示T应该是绑定类型的子类型,T和BoudingType可以是类也可以是接口。
可以通过 & 来进行多个限定。例如 T extends Comparable & Serializable
泛型代码和虚拟机
泛型类型代码都会被翻译成普通类,泛型类型被擦除掉;也就是说虚拟机中没有泛型类型对象。
约束和局限性
- 不能用基本类型实例化类型参数
- 运行类型检查(instanceof)只适用于原始类型
- 不能创建参数化类型的数组
- 不能实例化类型变量
- 泛型类的静态上下文中类型变量无效
- 不能抛出和捕获反省类的实例
通配符类型
- 类型限定(协变)
?extends BoudingType
可以作为返回值,不能作为参数传递 - 超类型限定(逆变)
? super BoudingType
不可以作为返回值,可以作为参数传递 - 无限制通配符
可以作为返回值,不能作为参数传递
协变和逆变
Number num = new Integer(1);
ArrayList<Number> list = new ArrayList<Integer>(); //type mismatch
List<? extends Number> list = new ArrayList<Number>();
list.add(new Integer(1)); //error
list.add(new Float(1.2f)); //error
? extends Number 表示 绑定类型是Integer或者Float等,具体类型不清楚,所以调用add会报错。
定义:
- 当A ≦ B时,如果有f(A) ≦ f(B),那么f叫做协变;
- 当A ≦ B时,如果有f(B) ≦ f(A),那么f叫做逆变;
- 如果上面两种关系都不成立则叫做不可变。
使用总结:
- 要从泛型类取数据时,用extends;
- 要往泛型类写数据时,用super;
- 既要取又要写,就不用通配符(即extends与super都不用)。