美文网首页学习
深入理解Java中的泛型(三)泛型类型擦除与泛型转译

深入理解Java中的泛型(三)泛型类型擦除与泛型转译

作者: 不思进取的码农 | 来源:发表于2021-08-23 14:36 被阅读0次

什么是泛型类型擦除

先看一道经典的测试题

List<String> list1 = new ArrayList<String>(); 
List<Integer> list2 = new ArrayList<Integer>();
System.out.println(list1getClass() == list1.getClass()); 

上面代码最终结果输出的是什么?不了解泛型的和很熟悉泛型的同学应该能够答出来,而对泛型有所了解,但是了解不深入的同学可能会答错。

正确答案是 true。

上面的代码中涉及到了泛型,而输出的结果缘由是类型擦除

简单概括泛型的类型擦除
泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。

通过泛型转译来解决类型擦除问题

public class Erasure <T>{
    T object;

    public Erasure(T object) {
        this.object = object;
    }
    
}

Erasure 是一个泛型类,我们查看它在运行时的状态信息可以通过反射

Erasure<String> erasure = new Erasure<String>("hello");
 Class eclz = erasure.getClass(); 
System.out.println("erasure class is:"+eclz.getName());

打印的结果是

erasure class is:com.frank.test.Erasure

Class 的类型仍然是 Erasure 并不是 Erasure<T>这种形式,那我们再看看泛型类中 T 的类型在 jvm 中是什么具体类型。

Field[] fs = eclz.getDeclaredFields();
for ( Field f:fs) {
    System.out.println("Field name "+f.getName()+" type:"+f.getType().getName());
}

打印结果是

Field name object type:java.lang.Object

那我们可不可以说,泛型类被类型擦除后,相应的类型就被替换成 Object 类型呢?

这种说法,不完全正确。

我们更改一下代码。

public class Erasure <T extends String>{
//  public class Erasure <T>{
    T object;

    public Erasure(T object) {
        this.object = object;
    }
    
}

现在再看测试结果:

Field name object type:java.lang.String

我们现在可以下结论了,在泛型类被类型擦除的时候,之前泛型类中的类型参数部分如果没有指定上限,如<T>则会被转译成普通的 Object 类型,如果指定了上限如<T extends String>则类型参数就被替换成类型上限。

相关文章

  • 【进阶之路】Java的类型擦除式泛型

    【进阶之路】Java的类型擦除式泛型 Java选择的泛型类型叫做类型擦除式泛型。什么是类型擦除式泛型呢?就是Jav...

  • Android 开发也要掌握的Java知识 - Java泛型

    如果需要看泛型擦除Java泛型擦除 1.Java泛型有什么用?为啥要使用泛型? Java中数组的类型是定义的时候就...

  • Java泛型:类型擦除

    前情回顾 Java泛型:泛型类、泛型接口和泛型方法 类型擦除 代码片段一 显然在平时使用中,ArrayList (...

  • java_泛型

    类型擦除正确理解泛型概念的首要前提是理解类型擦除(type erasure)。 Java中的泛型基本上都是在编译器...

  • 深入理解Java中的泛型(三)泛型类型擦除与泛型转译

    什么是泛型类型擦除 先看一道经典的测试题 上面代码最终结果输出的是什么?不了解泛型的和很熟悉泛型的同学应该能够答出...

  • Java 泛型与通配符

    参考地址:《Java 泛型,你了解类型擦除吗?》 《Java中的逆变与协变》 《java 泛型中 T、E .....

  • Java如何在运行时获取泛型的类型

    Java泛型是伪泛型,会在编译完成时进行类型的擦除,我们无法在运行时获取泛型参数的具体类型(类型擦除会被替换成泛型...

  • 泛型中 ? super T和 ? extends T的区别

    首先, 说到 Java 的泛型, 我们必须要提到的是Java 泛型的类型擦除机制: Java中的泛型基本上都是在编...

  • java泛型

    java的泛型是"伪泛型",为什么这么说。因为泛型只是作用在编译之前,编译之后,泛型都被擦除了(类型擦除)。所以说...

  • Java 泛型擦除原理

    问:请比较深入的谈谈你对 Java 泛型擦除的理解和带来的问题认识? 答:Java 的泛型是伪泛型,因为在编译期间...

网友评论

    本文标题:深入理解Java中的泛型(三)泛型类型擦除与泛型转译

    本文链接:https://www.haomeiwen.com/subject/srilbltx.html