Java泛型之类型擦除
2017-12-05 Java 泛型,
类型擦除 9 评论 字数统计: 1,214(字) 阅读时长: 6(分)
类型擦除
====
学过C++模板的,在使用Java泛型的时候,会感觉到有点不疑问,例如:(1)无法定义一个泛型数组、无法调用泛型参数对象中对应的方法(当然,通过extends关键字是可以做到,只是比较麻烦);(2)ArrayList和ArrayList
在运行时的类型是相同的。Java中的泛型有这些问题,是它的实现机制决定的,即“类型擦除”。
- 类型擦除的定义:编译通过后,准备进入JVM运行时,就不再有类型参数的概念,换句话说:每定义一个泛型类型,JVM会自动提供一个对应的原生类;
1 | 复制代码public class Holder4<T> { |
在Java中,每定义一个泛型类型,就会自动提供一个对应的原始类型,例如:
1 | 复制代码public class Holder4Raw { |
- 为什么选择这种实现机制?
* 在Java诞生10年后,才想实现类似于C++模板的概念,即泛型;
* Java的类库是Java生态中非常宝贵的财富,必须保证向后兼容(即现有的代码和类文件依旧合法)和迁移兼容(泛化的代码和非泛化的代码可互相调用)基于上面这两个背景和考虑,Java设计者采取了“类型擦除”这种折中的实现方式。
- Java泛型依赖编译器实现,只存在于编译期,JVM中没有泛型的概念;那么,编译器做了什么工作呢?(1)set方法是编译期检查;(2)get方法的返回值进行转型,编译器插入了一个checkcast语句。
我们通过字节码进行观察,可以看出:(1)Holder4和Holder4Raw两个类的字节码完全相同;(2)在main函数的33、41和49行就是编译器插入的checkcast语句;
1 | 复制代码public class org.java.learn.generics.Holder4<T> { |
参考资料
- 《Java编程思想》
- 《Effective Java》
- 《Java核心技术》
阿杜Java Developer
Thoughts, stories and ideas.
本文转载自: 掘金