《Java核心技术卷1:基础知识》CH8-泛型程序设计
8.1 为什么要使用泛型程序设计
泛型程序设计(Generic programming),意味着编写的代码可以被很多不同类型的对象所重用,从而减少重复代码的数量。
例如,ArrayList类,可以将任意类型的对象组合成动态数组,它就使用到了泛型的技术。
8.1.1 类型参数的好处
例如,ArrayList<String> files = new ArrayList<String>(),类型参数是String,它表明动态数组中的元素是String对象,从而使得泛型有更好的可读性。
8.1.2 谁想成为泛型程序员
实现一个泛型类是一件很困难的事情,应用Java的程序员一般不会涉及到开发泛型类的工作。JDK的开发者已经做出了很大努力,为所有的集合类都提供了类型参数。
8.2 定义简单泛型类
泛型类,是具有一个或多个类型变量的类。在Java库中,使用变量E表示集合的元素类型,K/ V表示映射的键和值,T表示任意类型。也可以使用多个泛型的类型参数,例如public class Pair(T1, T2)
// 自定义泛型类的demo public class Pair<T> // 类型变量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; } }
8.3 泛型方法
方法也可以利用泛型的方式定义,针对不同类型的参数输出不同的结果,从而精简代码开发量。泛型方法可以定义在普通类中,也可以定义在泛型类中。
// 泛型方法的demo public class ArrayAlg { public static <T> T getMiddle(T... a) { return a[a.length / 2]; } } /** 调用泛型方法时,如下所示 * String middle = ArrayAlg.<String>getMiddle("John", "Q.", "Public"); * String middle = ArrayAlg.getMiddle("John", "Q.", "Public"); */
8.4 类型变量的限定
这一小节暂时不是很理解,等待在实际工作中去使用。
8.5 泛型代码和虚拟机
虚拟机没有泛型类型对象,所有对象都属于普通类。这部分主要讲述虚拟机中的泛型类编译原理,暂时不是很理解。
8.5.1 类型擦除
8.5.2 翻译泛型表达式
8.5.3 翻译泛型方法
8.5.4 调用遗留代码
8.6 约束与局限性
这一节阐述Java泛型中遇到的限制。这类限制大多是由类型擦除引起的。
8.6.1 不能用基本类型实例化类型参数
基本类型无法作为泛型的类型参数,例如,没有Pair<double>,只有Pair<Double>
8.6.2 运行时类型查询只适用于原始类型
8.6.3 不能创建参数化类型的数组
不能实例化参数类型的数组,例如,Pair<String>[] pair = 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 泛型类型的继承规则
8.8 通配符类型
8.8.1 通配符概念
8.8.2 通配符的超类型限定
8.8.3 无限定通配符
8.8.4 通配符捕获
8.9 反射和泛型
8.9.1 泛型Class类
8.9.2 使用Class参数进行类型匹配
8.9.3 虚拟机中的泛型类型信息
上一篇:
IDEA上Java项目控制台中文乱码