Java基础之类型擦除
首先我们来看一个简单案例,这是一个简单的泛型类,我们通过反射查看T是什么类型
public class MyT { 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 stringMyT = new MyT(); Method[] methods = stringMyT.getClass().getDeclaredMethods(); for (Method method : methods) { System.out.println(method.getName()+"返回的类型为:"+method.getReturnType().getName()); } } }
可以看到,即使指定了泛型类型,在获取返回类型时泛型类型依然是Object。
接下来我们修改一下MyT类,将泛型添加限定指定T继承自String
public class MyT { 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 stringMyT = new MyT(); 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等。其实在使用的时候还是进行带强制类型的转化,只不过这是比较安全的转换,因为在编译阶段已经确保了数据的一致性。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。