一个由Java泛型类型擦除引起的问题

问题发生

  1. 项目工具及框架: mybatis-plus,springboot,jackson做json序列化处理器。
  2. 业务需求:搞了一个字段,字段类型是json。字段在java对应中对应的属性是一个枚举类型的List.
  3. 展现情况:利用mybatis-plus,存入时很正常的存入了枚举name组成的数组。查看的时候出现了问题,取出对象时是正常的。而当我访问那个枚举数组时,只要一访问这其中的元素,就出现了报错。
    java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum

问题定位

当时第一反应肯定是自己代码写的有问题,因为单个枚举类是可以直接转换的,存取都没有问题。确认了一下,没有问题。

然后也排除了jackson,mybatis-plus的问题,因为存入是正常的,而且报错的异常似乎来自于jdk。

最后通过断点和vm那些命令的方式,发现在访问这个元素前,我看不到这个数组下面的元素类型居然是string。。

确定问题–Java类型擦除

由于java的泛型是伪泛型,因为Java在编译期间,所有的泛型相关信息都会被“擦掉“,字节码中不包含任何类型信息,简单来说在编译器层次实现泛型时,生成的字节码是不包含泛型中的类型信息的。

举个例子,比如List和HashMap这样的容器,如论List还是List 在编译过程中,都会变成List,JVM对泛型是看不到的(C++没有这个坑),在对访问这些元素的时候,有时候就会出现问题。因为访问元素时会更具类型走强转,比如说Object i ,会用(Integer)i,如果是基本类型的包装类确实可以直接强转,而使用枚举类,强转就会报上面的错。

解决问题

目前用的一种比较粗暴的方法。声明一个类继承ArrayList,声明构造方法,使用这个类去定义属性即可。

应该还有从枚举本身出发的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值