Java泛型之类型擦除

泛型的基本原理

泛型出现的主要原因是为了创建容器类。泛型本质上是将数据类型参数化,它通过类型擦除的方式来实现。 声明了泛型的 .java 源代码,在编译生成 .class 文件之后,泛型相关的信息就消失了。 可以认为,源代码中泛型相关的信息,就是提供给编译器用的。 泛型信息对 Java 编译器可以见,对 Java 虚拟机不可见

类型擦除

使用泛型的时候加上的类型参数,会在编译的时候被编译器去掉。在这里,我们定义一个泛型类GenericsTest,下面的三段代码,分别是编译前的GenericsTest.java文件,经过编译器编译的GenericsTest.class文件,与从.class文件反编译后得到的GenericsTest.jad文件(我用的jad反编译的–jad下载地址):

//编译前的.java文件
public class GenericsTest<T> {
    private T arg1;
}
//经过编译器编译得到的.class文件
public class GenericsTest<T> {
    private T arg1;
	//可以看到编译器帮助我们生成一个默认的无参构造器,这个并不是本文的重点
    public GenericsTest(){}
}

//从.class文件反编译得到的文件
public class GenericsTest
{
	private Object arg1;
    public GenericsTest(){}
}

注意在第三段代码当中,类名后<T>被消除,且参数arg1的变成了Object类型,这个就是类型擦除。那么是不是所有的泛型都会使用Object来进行类型擦除呢?答案是NO。

大部分情况下在类型擦除中,泛型类型都用Object类型来替换,除了用到extendssuper语法的有界类型。比如下面的代码,通过extends,泛型T被规定为String的子类。可以看到反编译得到的代码中,参数arg1的变成了String类型,也就是用String来进行类型擦除。 因为T 被限定为 String或者 String的子类,也就是你构建 GenericsTest 实例的时候只能限定 T 为 String 或者 String 的子类。所以无论你限定 T 为什么类型,String 都是父类,不会出现类型不匹配的问题,因此可以使用 String 进行类型擦除

//编译前的.java文件
public class GenericsTest<T extends String> {
    private T arg1;
}
//从.class文件反编译得到的文件
public class GenericsTest
{
	private String arg1;
    public GenericsTest(){}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值