泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。
泛型类 :就是具有一个或多个类型变量的类。类定义中的类型变量指定方法的返回类型以及域和局部变量的类型、
public class Pair<T>{
private T first;
private T second;
public T getFirst(){}
public T getSecond(){}
public void setFirst(T newvalue){}
public void setSecond(T newvalue){}
}
泛型类的实例化:用具体的类型替换类型变量。 Pair<String> pair=new Pair<String>();
泛型方法:带有类型参数的简单方法。可以定义在普通类里面也可以定义在泛型类里。类型参数放在修饰符前,返回参数后。
public static <T> T getMiddle(T... a){return a[a.length /2];}
调用一个泛型方法:在方法名前的尖括号中放入具体的类型。可省略。
String middle=ArrayAlg.<String>getMiddle("zhang","rer","qqqwe");
类型变量的限定:假如有一种情况,一个方法是用来对参数进行排序,这就需要类型T实现了Comparable接口。
public static <T extends Comparable> T min(T[] a)...
<T Extends BoundingType> 表示T应该是绑定类型的子类型。T和绑定类型可以是类也可以是接口,所以用extends
泛型代码和虚拟机:
虚拟机没有泛型类型对象,也就是说所有对象属于普通类。
无论何时定义了一个泛型类型,都自动提供了一个相应的原始类型。原始类型的名字就是删去类型参数后的泛型类型名。
擦除类型变量,并替换为限定类型(无限定的变量用Object)
泛型的约束与局限性:
1.不能用基本类型实例化类型参数。 没有Pair<double> 只有Pair<Double> 因为Object不能存储double值
2.运行时类型查询只是用于原始类型。if(a instanceof Pair<String>) if(a instanceof Pair<T>)都是错的
3.不能创建参数化类型的数组。 Pair<String>[]table=new Pair<String>[10];是错的。而声明一个数组变量是可以的
4.Varargs警告:向参数个数可变的方法传递一个泛型类型的实例。
5.不能实例化类型变量。不能使用像new T(),new T[],T.class这样的表达式中的类型变量。
6.泛型类的静态上下文中类型变量无效。不能再静态域或静态方法中引用类型变量
7.不能抛出或捕获泛型类的实例。泛型类不能扩展Throwable
8.注意擦除后的冲突。
通配符: Pair<? extends Employee> 表示任何泛型Pair类型,它的类型参数是Employee的子类,如Pair<Manager>
通配符的超类型限定:? super Manager 这个通配符限定为Manager所有的超类型