注意:
◆泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。
◆泛型类型提供了一个更好的解决方案:类型参数。ArrayList类有一个类型参数用来指示元素的类型:
ArrayList<String> files = new ArrayList<String>();
◆一个泛型类就是具有一个或多个类型变量的类。
◆类定义中的类型变量指定方法的返回类型以及域和局部变量的类型。例如:private T first;//use type variable
◆在Java库中,使用变量E表示集合的元素类型,K和V分别表示表的关键字与值得类型,T可以表示“任意类型”。
◆用具体的类型替换类型变量就可以实例化泛型类型。换句话说,泛型类可以看成普通类的工厂。
◆静态的minmax方法遍历了数组并同时计算出最小值和最大值。回想一下CompareTo方法比较两个字符串,如果字符串相同,则返回0;如果按照字典顺序,第一个字符串比第二个字符串靠前,就返回负值,否则返回正值。
◆泛型方法可以定义在普通类中,也可以定义在泛型类中。当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型:
String[] names={"John", "Q.", "Public"};
String middle=ArrayAlg.<String>getMiddle(names);
在这种情况下,方法调用中可以省略类型参数。编译器有足够的信息能够推断出所调用的方法。它用names的类型(即String[])与泛型类型T[]进行匹配并推断出T一定是String。也就是说,可以调用
String middle=ArrayAlg.getMiddle(names);
一.泛型
1.虚拟机没有泛型类型对象——所有对象都属于普通类。
2.无论何时定义一个泛型类型,都自动提供了一个原始类型。原始类型的名字就是删去类型参数后的泛型类型名。擦除类型变量,并替换为现代类型(无限定的变量用Object)。
3.有关Java泛型转换的事实:
●虚拟机中没有泛型,只有普通的类和方法。
●所有的类型参数都用它们的限定类型转换。
●桥方法被合成来保持多态。
●为保持类型安全性,必要时插入强制类型转换。
4.不能用类型参数代替基本类型。即就是没有Pair<double>
,只有Pair<Double>
。
5.虚拟机中的对象总有一个特定的非泛型类型。因此,所有的类型查询只产生原始类型。
6.不能抛出也不能捕获泛型类的对象。事实上,泛型类扩展Throwable都不合法。
7.不能声明参数化类型的数组。
二.通配符
1.通配符限定与类型变量限定十分相似,但是,还有一个附加的额能力,可以制定一个超类型限定。
2.直观地讲,带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。
3.可以使用无限定的通配符。例如:Pair<?>
。
4.通配符捕获只有子啊许多限制的情况下才是合法的,编译器必须能够确信通配符表达的是单个、确定的类型。
5.可以使用Java SE 5.0增加的反射API来确定:
●这个泛型方法有一个叫做T的类型参数。
●这个类型参数有一个子类型限定,其自身又是一个泛型类型。
●这个限定类型有一个通配符参数。
●这个通配符参数有一个超类型限定。
●这个泛型方法有一个泛型数组参数。
6.为了表达泛型类型声明,Java SE 5.0在java.lang.reflect包中提供了一个新的接口Type。这个接口包含下列子类型:
●Class类,描述具体类型。
●TypeVariable接口,描述类型变量
●WildcardRType接口,描述通配符。
●ParameterizedType接口,描述泛型类或接口类型。
●GenericArrayType接口,描述泛型数组。