擦拭法 -> Type Erasure

擦拭法是指,虚拟机对泛型其实一无所知,所有的工作都是编译器做的。
因此,Java实现擦拭法实现了泛型,导致了

  • 编译器把类型<T>视为Object
  • 编译器根据<T>实现安全的强制转型。

也就是说,我们编写泛型的代码,实际上虚拟机执行的代码并没有泛型,全部是用Object来进行强制转换。
故,Java泛型的局限为:
局限一:<T>不能是基本类型,例如int,因为实际类型是ObjectObject类型无法持有基本类型

  1. Pair<int> p = new Pair<>(1, 2); // compile error!

局限二:无法取得带泛型的Class
所有的泛型实例,无论T的类型是什么,getClass返回同一个Class实例,因为编译后他们全都是Object
局限三:无法判断带泛型的Class

  1. Pair<Integer> p = new Pair<>(123, 456);
  2. // Compile error:
  3. if (p instanceof Pair<String>.class) {
  4. }

原因和前面一样,并不存在Pair<String>.class,而是只有唯一的Pair.class
局限四:不能实例化T类型:

  1. public class Pair<T> {
  2. private T first;
  3. private T last;
  4. public Pair() {
  5. first = new T();// Compile error:
  6. last = new T();// Compile error:
  7. }
  8. }