擦拭法 -> Type Erasure
擦拭法是指,虚拟机对泛型其实一无所知,所有的工作都是编译器做的。
因此,Java实现擦拭法实现了泛型,导致了
- 编译器把类型
<T>
视为Object
; - 编译器根据
<T>
实现安全的强制转型。
也就是说,我们编写泛型的代码,实际上虚拟机执行的代码并没有泛型,全部是用Object
来进行强制转换。
故,Java泛型的局限为:
局限一:<T>
不能是基本类型,例如int
,因为实际类型是Object
,Object
类型无法持有基本类型:
Pair<int> p = new Pair<>(1, 2); // compile error!
局限二:无法取得带泛型的Class
。
所有的泛型实例,无论T
的类型是什么,getClass
返回同一个Class
实例,因为编译后他们全都是Object
局限三:无法判断带泛型的Class
:
Pair<Integer> p = new Pair<>(123, 456);
// Compile error:
if (p instanceof Pair<String>.class) {
}
原因和前面一样,并不存在Pair<String>.class
,而是只有唯一的Pair.class
。
局限四:不能实例化T
类型:
public class Pair<T> {
private T first;
private T last;
public Pair() {
first = new T();// Compile error:
last = new T();// Compile error:
}
}