Java泛型擦除的补偿
public class Main<T> {
public T makeArray() {
// error: Type parameter 'T' cannot be instantiated directly
return new T;
}
}
我们无法在泛型内部创建一个T类型的对象,因为在运行时T仅仅是个占位符,并没有真实的类型信息,实际上,除了new表达式之外,instanceof操作和转型(会收到警告)在泛型内部都是无法使用的,而造成这个的原因就是之前讲过的编译器对类型信息进行了擦除。如果编译时不报错,那么将会在运行时出现异常。故在编译时即报错。
为什么还要使用泛型:
public class Main<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Main<String> m = new Main<String>();
m.set("findingsea");
String s = m.get();
System.out.println(s);
}
}
/* Output
findingsea
*/
虽然有类型擦除的存在,使得编译器在泛型内部其实完全无法知道有关T的任何信息,但是编译器可以保证重要的一点:内部一致性,也是我们放进去的是什么类型的对象,取出来还是相同类型的对象,这一点让Java的泛型起码还是有用武之地的。
代码片段四展现就是编译器确保了我们放在t上的类型的确是T(即便它并不知道有关T的任何类型信息)。这种确保其实做了两步工