首先我们来看一个简单案例,这是一个简单的泛型类,我们通过反射查看T是什么类型
public class MyT<T> {
private T info;
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
}
public class Demo {
public static void main(String[] args) {
Method[] methods = MyT.class.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName()+"返回的类型为:"+method.getReturnType().getName());
}
}
}
以上方法返回结果为
由此我们可以看到,getInfo方法在没有指定泛型类型的时候返回类型为Object类型,如果我们呢加上返回类型结果是否会不一样呢?
public class Demo {
public static void main(String[] args) {
MyT<String> stringMyT = new MyT<String>();
Method[] methods = stringMyT.getClass().getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName()+"返回的类型为:"+method.getReturnType().getName());
}
}
}
可以看到,即使指定了泛型类型,在获取返回类型时泛型类型依然是Object。
接下来我们修改一下MyT类,将泛型添加限定指定T继承自String
public class MyT<T extends String> {
private T info;
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
}
public class Demo {
public static void main(String[] args) {
Method[] methods = MyT.class.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName()+"返回的类型为:"+method.getReturnType().getName());
}
}
}
执行结果如下
由此我们可以看到,T被替换成String类型,在存在多个限定符时,T会转化成第一个限定符类型
现在将限定符去掉,接着进行测试
public class Demo {
public static void main(String[] args) {
MyT<String> stringMyT = new MyT<String>();
stringMyT.setInfo("hello");
Method[] methods = stringMyT.getClass().getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName()+"返回的类型为:"+method.getReturnType().getName());
}
String info = stringMyT.getInfo();
System.out.println(info);
}
}
运行结果如下
这里存在一个问题,首先是我们可以确定的是,getInfo()返回类型在运行时确定为Object类型,但是在stringMyT.getInfo()时,我们并没有对返回结果进行强转但是却可以被String类型的变量接收。实际上在编译时,编译器会自动进行强转
这是编译后的class文件,可以看到编译后的文件确实自动进行了强转,即使将MyT类中的info属性使用public修饰在调用时用String变量接收也是可以的。
String info = stringMyT.info;
总结
因为泛型其实只是在编译器中实现的而虚拟机并不认识泛型类项,所以要在虚拟机中将泛型类型进行擦除。也就是说,在编译阶段使用泛型,运行阶段取消泛型,即擦除。 擦除是将泛型类型以其父类代替,如String 变成了Object等。其实在使用的时候还是进行带强制类型的转化,只不过这是比较安全的转换,因为在编译阶段已经确保了数据的一致性。