一、泛型主要用法
1 泛型类
Pair 类引人了一个类型变量 T,用尖括号 ( < >) 括起来,并放在类名的后面。
public class Pair<T>
泛型类可以有多个类型变量。
例如, 可以定义 Pair 类,其中第一个域和第二个域使用不同的类型:
public class Pair<T, U> { . . . }
类定义中的类型变量指定方法的返回类型以及域和局部变量的类型。例如:
private T first; // uses the type variable
例子:
public 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 newValue) {
first = newValue;
}
public void setSecond(T newValue) {
second = newValue;
}
}
2 泛型方法
定义一个带有类型参数的方法:
class ArrayAlg {
public static <T> T getMiddle(T... a) {
return a[a.length / 2];
}
}
类型变量放在修饰符(这里是 public static) 的 后面,返回类型的前面。
泛型方法可以定义在普通类中,也可以定义在泛型类中。
当调用一个泛型方法时 , 在方法名前的尖括号中放人具体的类型:
String middle = ArrayAlg.<String>getMiddle("]ohnM, "Q", "Public");
3 限定泛型类型变量
public static <T extends Comparable > T a) {}
上面代码将 T 限制为实现\继承了 Comparable 接口\类的类。
4 通配符
1)上限
ArrayList<? extends Employee>
表示Employee类和继承Employee类的集合
不能传递参数,但能使用返回值
只能读,不能写
2)下限
ArrayList<? super Manager>
表示Manager类和Manager超类的集合
可以为方法提供参数, 但不能使用返回值。
只能写,不能读
3)无限定通配符
Pair<?>
暂时不知道用法,之后补充
二、为啥用泛型
由上面介绍泛型的用法可以看出,泛型有以下两点好处:
1 适用于多种数据类型执行相同的代码(代码复用)
2 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
三、泛型的局限性
1 不能用基本类型实例化类型参数
没有 Pair<double>, 只 有 Pair<Double>。
原因是类型擦除。擦除之后,Pair 类含有 Object 类型的域,而 Object 不能存储 double值。
2 运行时类型查询只适用于原始类型
3 不能创建参数化类型的数组
Pair[] table = new Pair[10]; // Error
4 不能实例化类型变量
不能使用像 new T(…),newT[…] 或 T.class 这样的表达式中的类型变量。
5 泛型类的静态上下文中类型变量无效
6 不能抛出或捕获泛型类的实例
既不能抛出也不能捕获泛型类对象。实际上, 泛型类扩展 Throwable 都是不合法的。
// Error can't extend Throwable
public class Problem<T> extends Exception { /* ...*/ }