[1]虚拟机中没有泛型,只有普通的类和方法
[2]所有的类型参数都用它们的限定类型替换
无论何时定义一个泛型类型,都自动提供了一个相应的原始类型。原始类型的名字就是删去类型参数后的泛型类型名。擦除类型变量,并替换为限定类型(无限定的变量用 Object)
如Pair的原始类型:
public class Pair {
private Object first;
private Object second;
public Pair(Object first, Object second) {
this.first = first;
this.second = second;
}
}
以上是无限定的情况,接下来是有限定的情况。有限定则原始类型用第一个限定的类型变量来替换:
public class Interval<T extends Comparable & Serializable> {
private T lower;
private T upper;
public Interval(T first,T second) {
...
}
}
它的原始类型为:
public class Interval {
private Comparable lower;
private Comparable upper;
public Interval(Comparable first, Comparable second) {
...
}
}
[3]为保持类型安全性,必要时插入强制类型转换
如:
Pair<Employee> buddies = ...;
Employee buddy = buddies.getFirst();
编译器把这个方法的调用翻译为两条虚拟机指令:
1.对原始方法Pair.getFirst的调用
2.将返回的Object类型强制转换为Employee类型
[4]桥方法被合成来保持多态
class DateInterval extends Pair<LocalDate> {
public void setSecond(LocalDate second) {
if(second.compareTo(getFirst()>=0)
super.setSecond(second);
}
}
它的原始类型为:
class DateInerval extends Pair {
public void setSecond(LocalDate second) {...}
}
它从Pair中也继承了一个setSecond方法:
public void setSecond(Object second);
那么
DateInterval interval = new DateInterval(...);
Pair<localDate>pair = interval;
pair.setSecond(aDate);
此时的调用要具有多态性并调用最适合的方法,因此,就需要编译器在DateInterval类中生成一个桥方法:
public void setSecond(Object second) {
setSecond((Date) second);
}
首先,变量pair已经声明为类型Pair,并且这个类型只有一个简单的方法叫setSecond,即setSecond(Object)。虚拟机用pair引用的对象调用这个方法。这个对象是DateInterval类型的,因而会调用DateInterval.setSecond(Object)方法。这个方法是合成的桥方法,它调用DateInterval.setSecond(Date),这正是我们所期望的操作效果。
注:本文为《Java 核心技术 卷I》读书笔记及个人理解解释