学习总结 - java 泛型擦除问题

ゝ一纸荒年。 2022-03-21 06:08 248阅读 0赞

java泛型擦除

Java的泛型是伪泛型。在编译期间,所有的泛型信息都会被擦除掉。正确理解泛型概念的首要前提是理解类型擦出(type erasure)

Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。

如在代码中定义的List和List等类型,在编译后都会编程List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。

Java 方法重载 — 泛型参数

首先看一段代码
虽然泛型不同,但是依然不能重载,编译根本不能通过

  1. public void addData(List<TaskRequest> list) {
  2. if (list == null || list.isEmpty()) {
  3. return;
  4. }
  5. }
  6. public void addData(List<TaskBean> list) {
  7. if (list == null || list.isEmpty()) {
  8. return;
  9. }
  10. }

泛型数组

  • 不能直接创建泛型数组

  • 泛型数组实际的运行时对象数组只能是原始类型( T[]为Object[],Pair[]为Pair[] ),而实际的运行时数组对象可能是T类型( 虽然运行时会擦除成原始类型 )

  • 一般解决方案:(泛型数组包装器):使用ArrayList收集泛型数组对象的对象元素,如ArrayList、ArrayList>

创建泛型数组 解决方案

通过反射在运行时构出实际类型为type[]的对象数组,避免了类型擦除,从而转换成功,无ClassCastException

  1. import java.lang.reflect.*;
  2. public class GenericArrayWithTypeToken<T> {
  3. private T[] array;
  4. @SuppressWarning("unchecked")
  5. public GenericArrayWithTypeToken(Class<T> type, int sz) {
  6. array = (T[]) Array.newInstance(type, sz);//通过反射在运行时构出实际类型为type[]的对象数组,避免了类型擦除,从而转换成功,无ClassCastException
  7. }
  8. public void put(int index, T item){
  9. array[index] = item;
  10. }
  11. public T get(int index) { return array[index]; }
  12. public T[] rep() { return array; } //能成功返回了~
  13. public static void main(String[] args) {
  14. GenericArrayWithTypeToken<Integer> gawtt = new GenericArrayWithTypeToken<>(Integer.class, 10);
  15. Integer[] ia = gawtt.rep(); //能成功返回了!
  16. }
  17. }

consult :

https://blog.csdn.net/u013467442/article/details/53411257

https://www.cnblogs.com/ixenos/p/5648519.html

发表评论

表情:
评论列表 (有 0 条评论,248人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java

    前言 本文讲从字节码层面深度学习泛型,这也是大厂常见面试 我们定义了如下类图所示类: ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5

    相关 Java-类型

    Java泛型-类型擦除 一、概述 Java泛型在使用过程有诸多的问题,如不存在List.class, List不能赋值给List(不可协变),奇怪的ClassCastE