最近在看《Java核心技术》泛型相关的部分,总结下。
泛型程序设计是什么?
泛型编程(generic programming)是计算机编程中的一种风格,类型通过参数指定。意味着编写的代码可以被不同类型的对象所使用。
类型参数(type parameters),指示类型。ArrayList用类型参数来指示包含元素的类型。使程序有更好的可读性和安全性。
解决什么问题?
使代码具有更好的可读性和安全性。
如何用
泛型类(generic class)具有一个或多个类型参数的类。如下所示,用具体的类型替换类型变量就可以实例化类型参数,Pair<String>。
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 void setFirst(T first) {
this.first = first;
}
}
泛型方法(generic method)。泛型方法可以定义在普通类中,也可以定义到泛型类中。
在普通类定义泛型方法
class ArrayAlg {
public static <T> T getMiddle(T... a) {
return a[a.length/2];
}
}
调用泛型方法,<String>大部分情况下可不写。
ArrayAlg.<String>getMiddle("John", "Q", "Public");
对于编译器无法确定参数类型会给出错误报告,如下所示。编译器会将参数打包成1个Double,2个Integer,并寻找其共同的超类,且找到两个Number和Comparable,会报错。
ArrayAlg.getMiddle(3.14, 1729, 0);
对类或方法的类型变量加以限定。
class ArrayAlg {
public static <T extends Comparable> T min(T... a) {
}
}
可以有多个限定,用&连接,但限定中至多有一个类,且必须是限定列表中的第一个。
T extends Comparable & Serializable
虚拟机没有泛型类型对象,所有对象都属于普通类。编译器会擦除(erased)类型变量,并替换为限定类型(如果没有限定类型,使用Object),使之成为原始类型(raw type)。Pair<T>的原始类型如下:
public class Pair {
private Object first;
private Object second;
}
关于Java泛型转换的事实:
虚拟机中没有泛型,只有普通的类和方法
所有的类型参数都用它们的限定类型替换
桥方法被合成来保持多态
为保持类型安全性,必要时插入强制类型转换