标签:
本文延续上文,针对泛型程序设计,从以下方面进行讲解:
这里内容比较多且杂,我们先概括几个主要思想:
(1)当定义一个泛型类型时,系统会自动提供一个相应的原始类型。原始类型的名字就是删去类型参数后的泛型类型名。擦除类型变量,并替换为限定类型。
(2)当程序调用泛型方法时,如果擦除返回类型,编译器就会插入相对应的强制类型转换。
下面深入探讨使用Java泛型时需要考虑的一些限制,大多数限制都是由类型擦除引起的
不能用类型参数代替基本类型,即没有Pair<double>
只有Pair<Double>
。这是因为类型擦除以后,Pair类含有Object类型的域,而Object不能存储double值。
虚拟机中的对象总有一个特定的非泛型类型,因此,所有的类型查询只产生原始类型。
不能使用像new T(···),new T[···]或者T.class这样的表达式中的类型变量。
简单说来,就是无论S与T有什么联系,通常Pair<S>
和Pair<T>
没有什么联系。例如Manager类是Employee类的子类,但Pair<Employee>
和Pair<Manager>
并没有什么关系。
固定的泛型类型系统使用起来很不爽,因此出现了通配符类型。例如
Pair<? extends Employee>
表示任何泛型Pair类型,它的类型参数是Employee的子类,如Pair<Manager>
而不会是Pair<String>
。
通配符限定与类型变量限定十分相似,但还有一个附加功能,即可以指定一个超类型限定。例如
? super Manager
这个通配符限制为Manager的所有超类型。
无限定通配符使用方式,如Pair<?>
。
通配符捕获只有在有许多限制的情况下才是合法的,编译器必须能够确信通配符表达的时单个的、确定的类型。
下面,我们用一个例程来回顾前面讲述的概念们
package pair3;
public class PairTest3
{
public static void main(String[] args)
{
Manager ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
Manager cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15);
Pair<Manager> buddies = new Pair<>(ceo, cfo);
printBuddies(buddies);
ceo.setBonus(1000000);
cfo.setBonus(500000);
Manager[] managers = { ceo, cfo };
Pair<Employee> result = new Pair<>();
minmaxBonus(managers, result);
System.out.println("first: " + result.getFirst().getName()
+ ", second: " + result.getSecond().getName());
maxminBonus(managers, result);
System.out.println("first: " + result.getFirst().getName()
+ ", second: " + result.getSecond().getName());
}
public static void printBuddies(Pair<? extends Employee> p)
{
Employee first = p.getFirst();
Employee second = p.getSecond();
System.out.println(first.getName() + " and " + second.getName() + " are buddies.");
}
public static void minmaxBonus(Manager[] a, Pair<? super Manager> result)
{
if (a == null || a.length == 0) return;
Manager min = a[0];
Manager max = a[0];
for (int i = 1; i < a.length; i++)
{
if (min.getBonus() > a[i].getBonus()) min = a[i];
if (max.getBonus() < a[i].getBonus()) max = a[i];
}
result.setFirst(min);
result.setSecond(max);
}
public static void maxminBonus(Manager[] a, Pair<? super Manager> result)
{
minmaxBonus(a, result);
PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type
}
}
class PairAlg
{
public static boolean hasNulls(Pair<?> p)
{
return p.getFirst() == null || p.getSecond() == null;
}
public static void swap(Pair<?> p) { swapHelper(p); }
public static <T> void swapHelper(Pair<T> p)
{
T t = p.getFirst();
p.setFirst(p.getSecond());
p.setSecond(t);
}
}
标签:
原文地址:http://blog.csdn.net/lipengcn/article/details/51355758