8. 泛型程序设计
8.1 为什么要使用泛型程序设计
8.1.1 类型参数的好处
使用类型参数让代码有更高的可读性, 让程序更宜读也更安全
var files = new ArrayList<string>();
8.1.2 谁想成为泛型程序员
8.2 定义简单泛型
java
public class Pair<T, U>
{
private T first;
private T second;
private U third;
public Pair() { first = null; second = null }
public Pair(T first, T second){ this.first = first;this.second= second;}
public T getFirst() { return first; }
public T getSecond() { return second; }
public void setfirst(T newValue) { first = newValue; }
public void setSecond(T newValue) { second = newValue; }
}
泛型是普通类的工厂
8.3 泛型方法
String middle = ArrayALg.<string> getMiddle("john", "Q.","Public");
8.4 类型变量的限定
限制 T 只能是实现了 Comparable 接口
// 限定类型
public static <T extends Comparable> T min(T[] a) . . .
// 多个限定
public static <T extends Comparable & Serializable> T min(T[] a) . . .
8.5 泛型代码和虚拟机
8.5.1 类型擦除
虚拟机在处理的时候会擦除掉类型
8.5.2 转换泛型表达式
转换泛型表达式的两个步骤是
- 转换为普通的类型
- 强制转换为 Employee 类型
8.5.3 转换泛型方法
- 虚拟机中没有泛型, 只有普通的类和方法
- 类型残水会替换为他们的限定类型
- 会合成桥方法来保持多态
- 为保持类型安全性, 必须时候会插入强制类型转换
8.5.4 调用遗留代码
在使用泛型的时候可能会遇到数据转换异常的情况, 这种情况可以使用 @SuppressWarnings("unchecked")
来进行忽略
8.6 [WIP]限制与局限性
8.6.1 不能用基本类型实例化类型参数
原因在于类型擦除, 擦除之后, Pair 类含有 Object 类型的字段, 而 Object 类
diff
- Pair<double>
+ Pair<Double>
8.6.2 运行时类型查询只适用于原始类型
虚拟机中的对象总有一个特定的非泛型类型, 因此所有类型查询只产生原始类型
同样的道理, getClass
方法总是返回原始类型
8.6.3 不能创建参数化类型的数组
可以声明 Pair<string>[]
的变量, 但是不能用 new Pair<string>[10]
初始化这个变量
8.6.4 Varargs 警告
8.6.5 不能实例化类型变量
8.6.6 不能构造泛型数组
8.6.7 泛型类的静态上下文中的类型变量无效
不能在静态字段或方法中引用类型变量
8.6.8 不能抛出或捕获泛型类的实例
8.6.9 可以取消对检查型异常的检查
8.6.10 注意擦除后的冲突
8.7 [WIP]泛型类型的继承规则
8.8 [WIP]通配符类型
8.8.1 通配符概念
允许类型参数发生变化, 这个可能更类似于 php 中的 “更灵活” 的接口约定
Pair<? extends Employee>
8.8.2 通配符的超类型限定
这个限定为所有 Manager 的超类型
? super Manager
8.8.3 无限定通配符
8.8.4 通配符捕获
8.9 [WIP]反射和泛型
说明
创建时间: 2023-11-19 19:27:00 , 最后编辑于 2023-11-19 20:45:00