所谓擦拭法是指,虚拟机对泛型其实一无所知,所有的工作都是编译器做的。 例如,我们编写了一个泛型类Pair,这是编译器看到的代码:
public class Pair<T> { private T first; private T last; public Pair(T first, T last) { this.first = first; this.last = last; } public T getFirst() { return first; } public T getLast() { return last; } }而虚拟机根本不知道泛型。这是虚拟机执行的代码:
public class Pair { private Object first; private Object last; public Pair(Object first, Object last) { this.first = first; this.last = last; } public Object getFirst() { return first; } public Object getLast() { return last; } }因此,Java使用擦拭法实现泛型,导致了:
编译器把类型视为Object;编译器根据实现安全的强制转型。使用泛型的时候,我们编写的代码也是编译器看到的代码:
Pair<String> p = new Pair<>("Hello", "world"); String first = p.getFirst(); String last = p.getLast();而虚拟机执行的代码并没有泛型:
Pair p = new Pair("Hello", "world"); String first = (String) p.getFirst(); String last = (String) p.getLast();所以,Java的泛型是由编译器在编译时实行的,编译器内部永远把所有类型T视为Object处理,但是,在需要转型的时候,编译器会根据T的类型自动为我们实行安全地强制转型。
