泛型擦除/类型擦除 + 泛型约束
泛型擦除什么是泛型擦除?什么是泛型擦除?Java 源代码中所使用的泛型
泛型擦除/类型擦除
优先看参考地址吧,都是大佬的文章,如下内容都是来自总结哈。
官方名称叫类型擦除(type erasure)
什么是泛型擦除?
Java 源代码中所使用的泛型,在编译器编译成字节码的过程中,泛型的类型参数会去掉,这个过程称为类型擦除。
泛型信息(类型变量、参数化类型)
泛型的类型参数去掉的时机
如下代码中泛型的类型参数String的去掉时机
List<String> list = new ArrayList<>();
String,不是在编辑了这行代码后去掉,而是在编辑器(java compiler)完成了对给定代码文档的全部编译(翻译成字节码文档 .class)之后,才丢掉的。
因此,在这行代码行(在创建了这个 字符串数组列表实体)之后,编译器才能时刻监视其中有关数组元素的操作,是否是符合 字符串 String 类型的操作规矩。
泛型的本质
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
伪泛型
因为有泛型擦除的存在,所以Java中的泛型又称为伪泛型。
类型
原始类型
原始类型(raw type)就是擦除去了泛型信息,最后在字节码中的类型变量的真正类型。无论何时定义一个泛型类型,相应的原始类型都会被自动地提供。类型变量被擦除(crased),并使用其限定类型(无限定的变量用Object)替换。
限定类型
如 Pair,Comparable就是限定类型;
如 Pair,Object就是限定类型
泛型擦除的场合
擦除规则
编译器会把泛型类型中所有的类型参数替换为它们的上(下)限,如果没有对类型参数做出限制,那么就替换为Object类型。因此,编译出的字节码仅仅包含了常规类,接口和方法。
详细:
若泛型类型没有指定具体类型,用Object作为原始类型;
若有限定类型< T exnteds XClass >,使用XClass作为原始类型;
若有多个限定< T exnteds XClass1 & XClass2 >,使用第一个边界类型XClass1作为原始类型;
类型转换
在必要时插入类型转换以保持类型安全。
桥方法
生成桥方法以在扩展泛型时保持多态性。
例子可以看 Java 泛型(擦除,转换,桥方法):https://blog.csdn.net/qq_43132512/article/details/93230313
为什么
为什么需要泛型擦除
考虑到字节码兼容性,向下兼容。
Java 5才引入了范型,在此之前都是没有范型的。
jvm 的 bytecode 不支持体现任何泛型信息(这是历史原因造成的缺陷),但是类型信息还有,所以就特别叫其泛型擦除。
泛型擦除为什么会导致泛型不安全
通俗一点,我们可以通过反射,向String的list内加integer的值
==
使用泛型以及泛型擦除带来的影响(副作用)== 泛型约束
转:https://blog.csdn.net/qq_40270270/article/details/112915355
- 泛型类型变量不能使用基本数据类型
- 不能使用instanceof运算符
- 泛型在静态方法和静态类中的问题
- 泛型类型中的方法冲突
- 没法创建泛型实例
- 没有泛型数组
既然泛型会被擦除,那么为什么不需要进行强制转换
Java的泛型类型擦除是发生在编译时的,在编译时会擦除泛型的参数化类型,并检查相应的代码,同时在相应的地方插入强制转换的代码。插入强制转换的代码可以通过反编译Java字节找到checkcast指令可知。
参考地址
Java 泛型擦除:https://www.oschina.net/question/3939240_2316318
基础知识-Java泛型擦除(简洁明了):https://blog.csdn.net/qq_30878303/article/details/79639904
Java 的泛型擦除和运行时泛型信息获取
转 :https://www.zhihu.com/question/452958728/answer/1817841881
原:https://my.oschina.net/lifany/blog/875769
Java中的反射真的可以获取泛型属性吗
https://jasonkayzk.github.io/2020/03/25/
Java中的泛型会被类型擦除,那为什么在运行期仍然可以使用反射获取到具体的泛型类型:
https://blog.csdn.net/cpcpcp123/article/details/115141681
更多推荐
所有评论(0)