简单的泛型类
- 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。 
- 一个泛型类(generic class) 就是具有一个或者多个类型变量的类,且泛型类中可以有多个类型变量,类定义中的类型变量指定方法的返回类型以及域和局部变量的类型。 - 如:public class Pair\ - {…} -  private T first; 
- 在Java库中,使用变量E表示结合的元素类型,K和V分别表示表的关键字与值得类型,T(U,S) 表示任意类型。 
泛型方法
- 定义泛型方法时,类型变量放在修饰符(如public,static等)的后面,返回类型的前面。 - 如: 12345class ArrayAlg{public static <T> T getMiddle(T... a){return a[a.length/2];}}
- 泛型方法可以定义在普通类中,也可以定义在泛型类中,当调用一个泛型方法时,在方法名前的尖括号放入具体的类型也可以省略。 - 如: String middle= ArrayAlg.\ - getMiddle(); - 该调用中的 - <String>即可省略。
类型变量的限定
\
- 表示T应该是绑定类型(BoundingType)的子类型,T和绑定类型可以是类,也可以是接口。
- 限定类型用”&”分隔,类型变量用”,”分隔
- 在Java的继承中,可以根据需要拥有多个接口超类型,但限定至多只有一个类;如果用一个类作为限定,他必须是限定列表中的第一个。
泛型代码和虚拟机
- 虚拟机没有泛型类型对象,所有对象都属于普通类。
- 无论何时定义一个泛型类型,都自动提供了一个相应的原始类型。原始类型的名字就是删除类型参数后的泛型类型名。 擦除类型变量,并替换为限定类型(无限定用Object)。
- 类型擦除可能与多态发生冲突,可以利用桥方法来保持多态。
- 所有的类型参数都用他们的限定类型替换。
约束与局限性
- 类型参数不能使用基本类型,原因是类型擦除后,泛型类含有Object类型的域,而其不能存储基本类型(如double)的值。 
- 所有的类型查询只产生原始类型 - 如: 1234Pair<String> stringPair=...;Pair<Employee> employeePair=...;if(StringPair.getClass()==employeePair.getClass())//they are equal,与类型变量无关
- 不能创建参数化类型的数组,但是生命类型为Pair\ - []的变量仍为合法的,不过不能用new Pair\ - [10]初始化。 - 如果需要手机参数化类型对象,唯一安全有效的方法时使用ArrayList: - ArrayList<Pair<String>>
- 不能构造一个泛型数组,如果数组仅仅作为一个类的私有实力域,就可以将这个数组声明为Object[],并且在获取元素时进行类型转换。P541 
- 不能在静态域或者方法中引用类型变量 - 如: 123456789public class Singleton<T>{private static T singleInstance; //ERRORpublic static T getSingleInstance() //ERROR{if(ssingleInstance==null) construct new instance of Treturn singleInstance;}}- 类型擦除之后,T失效,只剩下Singleton类。 
泛型类型的继承规则
- 无论S与T有什么联系,通常,Pair\与Pair\没什么联系。 
- 泛型类可以扩展或实现其他的泛型类。例如:ArrayList\类实现了List\ 接口。 
通配符类型
- 通配符的超类型限定(例) - ? super Manager - 这个通配符限制为Manager的所有超类型,带有超类型限定的通配符可以为方法提供参数,但不能使用返回值。 
- 通配符的子类型限定(例) - ? extends Employee - 这个通配符限制为Employee的所有子类型,可以接受方法的返回值,但不能提供参数。即可以使用get()方法,但是无法使用set()方法。 
- 带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。 
- 无限定通配符 - Pair<?> - Pair<?>与Pair的本质不同在于:可以用任意Object对象调用原始的Pair类的setObject方法。