优先看参考地址吧,都是大佬的文章,如下内容都是来自总结哈。

官方名称叫类型擦除(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

  1. 泛型类型变量不能使用基本数据类型
  2. 不能使用instanceof运算符
  3. 泛型在静态方法和静态类中的问题
  4. 泛型类型中的方法冲突
  5. 没法创建泛型实例
  6. 没有泛型数组

既然泛型会被擦除,那么为什么不需要进行强制转换

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

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐