从字节码看泛型擦除问题

泛型简介

Java泛型是jdk1.5引入的新特性,但并不是由Java所引入的新概念,在Java正式使用泛型之前如果要实现类型泛化,都是通过直接在参数类型处使用Object,因为Object是所有类的父类,所以编译期都不会报错,可是一旦到了运行期,你不太可能确定真实的类型能够正确转换成你想要的类型。
在没有泛型之前:

/**
 * Son extends Father
 *
 * @author myllxy
 * @create 2019-12-15 22:04
 */
public class GenericTest1 {
    public static void main(String[] args) {
        testDemo1(new Father());
    }
	/**
     * 该方法中参数object是静态类型,静态类型的变化仅仅在使用时发生,
     * 变量本身的静态类型不会改变,并且最终的静态类型是在编译期可知的;
     * 而实际类型变化的结果在运行期在可以知道,编译器在编译程序的时候病
     * 不知道一个对象的实际类型是什么
     * 
     * 所以,在这个案例中我们可以看到,虽然最后报类型转换错误,但是编译期
     * 不会报错,因为Father确实能够直接向上转型成Object,注意着后面,
     * (Son)object是在=右边,相当于编译期编译期并不知道object是什么了
     * 他只是为了通过编码规定将object加了个(Son),但至于是否真的能转换
     * 看运行期了
     */
    private static void testDemo1(Object object) {
        Son son = (Son) object;
    }
}

所以到这儿我们就看到没有泛型时程序的弊端了,在加上泛型之后:

/**
 * Son extends Father
 *
 * @author myllxy
 * @create 2019-12-15 22:04
 */
public class GenericTest1 {
    public static void main(String[] args) {
        testDemo1(new Father());
    }
    /**
     * 在加上泛型后上面的testDemo1(new Father())就会报错了
     * 具体T extends Son牵涉到的泛型的协变与逆变问题不在这里赘述了
     */
    private static <T extends Son> void testDemo1(T t) {
        Son son = (Son) t;
    }
}

这就是泛型,它为我们在编译期就讲运行期可能的类型转换错误提前预知出来了

泛型擦除

先看这么一个案例:
在这里插入图片描述
按照重载的定义,List<Integer>、List<String>理论上是两个不同的类型吧,但是仍然在编译期被拒绝编译了
erasure这个单词就是擦除的意思
泛型中的类型在编译时被擦除,运行时会被替换为原生类型,所以List<Integer>、List<String>在运行期就是同一个类型,编译器就理所当然地阻止编译了。
这段代码的字节码如下:
在这里插入图片描述
Signature用于存储一个方法在字节码层面的特征签名
对泛型类型的局部变量,需要在LocalVariableTable Attribute和LocalVariableTypeTable Attribute中同时存在一项;而对非泛型类型的局部变量来说,只要在LocalVariableTable Attribute存在表项就可以了。

但是,仅仅对code属性中的字节码进行擦除,实际上元数据还是保留了泛型信息,这也是我们能通过反射来获取其参数化类型事务根本依据

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值