网站报301错误,南通城乡住房建设厅网站首页,建站公司会有多大的坑,wordpress可视化模板编辑器回答重点
泛型擦除指的是Java编译器在编译时将所有泛型信息删除的过程#xff0c;以确保与Java1.4及之前的版本保持兼容
泛型参数在运行时会被替换为其上界#xff08;通常是Object#xff09;#xff0c;这样一来在运行时无法获取泛型的实际类型。
作用#xff1a;泛型…回答重点
泛型擦除指的是Java编译器在编译时将所有泛型信息删除的过程以确保与Java1.4及之前的版本保持兼容
泛型参数在运行时会被替换为其上界通常是Object这样一来在运行时无法获取泛型的实际类型。
作用泛型擦除确保了Java代码的向下兼容性即可以与旧版本的Java代码兼容为了让使用泛型的代码在不同版本的Java运行时环境中都可以正常工作。又由于泛型类型信息在编译时期被擦除了因此运行时无法获取泛型信息这样就不能创建泛型类型的数组或对泛型类型使用instanceof检查
示例
public T void printList(ListT list) {for (T element : list) {System.out.println(element);}
}编译后的代码类似于
public void printList(List list) {for (Object element : list) {System.out.println(element);}
}类型T会被擦除成Object 扩展知识
为什么Java泛型的实现是类型擦除
回答重点提到了主要原因是为了向下兼容即兼容Java5之前编译的class文件。
例如Java1.2上正在跑的代码可以在Java1.5上的JRE上运行
也是因为需要向下兼容才使得Java实现的是伪泛型 我从现有的实现倒推伪泛型的设计可能思路个人瞎掰的做个参考即可
是这样的
这Java5以前的版本在线上已经有很多应用在跑了如果我的Java5不能兼容没人用啊泛型毕竟是加一个约束以前的代码没有这个约束啊该如何兼容有了要不我在编译器上动手动脚在编译的时候识别和约束泛型然后编译过了就把泛型的信息擦除了。这样运行的时候就没有约束了跟之前的版本就没什么区别了。
参考网上的解释 这说明写Java的也是程序员也是要发版有上线需求的
为什么运行期通过反射可以获得类型
public class GenericTest {public static void main(String[] args) {ListString list new ArrayList();list.add(hello);String s list.get(0);}
}
看字节码 从反编译看生成的字节码文件能看到new的List没有保存泛型所以是被擦除了
下面有一步checkcast强转为String可是Java代码中不需要写强转呢
因为编译器隐形的帮我们插入了强转的代码所以不需要我们写
再看标题既然擦除了类型为什么运行期还能通过反射获取类型
答案就藏在class文件中
看下面代码
获取泛型类型
public class GenericTest {public ListString list;public static void main(String[] args) throws Exception{Field field GenericTest.class.getField(list);Type type ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];System.out.println(type);}
}
javap -v可以看到字节码里记录了泛型类型信息所以编译器虽然擦除了泛型类型也记录了泛型信息自然能通过反射获取 由于静态记录在了字节码中所以局部变量这种存在栈中的泛型类型通过反射就无法获取
只有三种情况可以通过反射获取泛型类型
成员变量的泛型方法入参的泛型方法返回值的泛型类的泛型