public class TestF {
public static void main(String[] args) {
Class a1 = new ArrayList<Integer>().getClass();
Class a2 = new ArrayList<String>().getClass();
System.out.println(a1 == a2);
}
}
如果仅凭直觉来看,该程序可能会输出 false 这个结果,但在具体的环境下运行时会输出 true 。这很令人费解,这是为什么呢?
Java泛型是使用类型擦除来实现的。这表示在运行过程中任何和类型有关的信息都会被擦除,所有在运行中 ArrayList和ArrayList的具体信息都被擦除成它们的原生类型即ArrayList类型。
由于擦除机制,泛型不能用于显示地引用运行时类型的操作之中,例如转型、new表达式和instanceof操作。
若在泛型内部必须使用类型操作时,可以在运行时采用反射的方法将正在运行的类信息添加到泛型内部,这种方法称为补偿。
public class Dog {
public Dog() {
System.out.println("Dog...");
}
}
public class TestF2<T> {
Class<T> type;
public TestF2(Class<T> type) {
this.type = type;
}
public boolean check(Object obj) {
return type.isInstance(obj); //isInstance 和instanceof动态等价
}
public void show(Class<T> type) { //使用反射动态实现new表达式
try {
type.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestF2<Dog> t = new TestF2<Dog>(Dog.class);
System.out.println(t.check(new Dog()));
t.show(Dog.class);
}
}
输出为:
Dog…
true
Dog…