类型参数
- 可读性:一看就知道是什么类型
- 安全性:不是这个类型时会报编译错误
泛型类与泛型方法
public class TestGeneric {
public static void main(String[] args) {
// 测试泛型类
String[] words = {"Mary", "had", "a", "little", "lamb"};
Pair<String> mm = ArrayAlg.minmax(words);
System.out.println("min = " + mm.getFirst());
System.out.println("max = " + mm.getSecond());
// 测试泛型方法
String middle = ArrayAlg.middle("John", "Q", "Public");
System.out.println(middle);
}
}
/**
* 泛型类
* @param <T>
*/
class Pair<T> {
private T first;
private T second;
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 first) {
this.first = first;
}
public void setSecond(T second) {
this.second = second;
}
}
class ArrayAlg {
/**
* 泛型方法
* @param a
* @param <T>
* @return
*/
public static<T> T middle(T... a) {
return a[a.length / 2];
}
/**
* 类型变量的限定
* @param a
* @param <T>
* @return
*/
public static<T extends Comparable> T min(T[] a) {
if (a == null || a.length == 0) {
return null;
} else {
T min = a[0];
for (int i = 1; i < a.length; i++) {
if (min.compareTo(a[i]) > 0) {
min = a[i];
}
}
return min;
}
}
/**
* 取大小值
* @param a
* @param <T>
* @return
*/
public static <T extends Comparable> Pair<T> minmax(T[] a) {
if (a == null || a.length == 0) {
return null;
} else {
T min = a[0];
T max = a[0];
for (int i = 1; i < a.length; i++) {
if (min.compareTo(a[i]) > 0) {
min = a[i];
}
if (max.compareTo(a[i]) < 0) {
max = a[i];
}
}
Pair<T> mm = new Pair<>(min, max);
return mm;
}
}
}
类型擦除
原始类型的名字就是删除类型参数后的泛型类型名。擦除类型变量,并替换为限定类型(无限定的变量用Object)且有多个则用第一个。
翻译泛型
- 强制类型转换
- 生成桥方法
注:
- 没有泛型,只有普通类和方法
- 限定类型(或Object)替换类型参数
- 生成桥方法以保持多态
- 强制类型转换以保持类型安全性
类型擦除带来的约束与局限
- 不能用基本类型实例化类型参数
- 运行时类型查询只适用于原始类型
- 不能创建参数化类型的数组
- Varargs警告
- 不能实例化类型变量
- 不能构造泛型数组
- 泛型类的静态上下文中类型变量无效
- 不能抛出或捕获泛型类的实例
- 可以消除对受查异常的检查
- 当泛型类型被擦除时,无法创建引发冲突的条件
泛型类型的继承规则
无论S与T有什么联系,通常,P<S>与P<T>没有什么联系
通配符类型
- Pair<? extends Employee>表示任何泛型Pair类型,它的类型参数是Employee的子类
- ?super Manager限制为Manager的所有超类型
- Pair<?>
- 通配符捕获
反射与泛型
- 泛型Class类
- 使用Class<T>参数进行类型匹配
- Type接口