java类型擦除怎么解决_记一次由于Java泛型类型擦除而导致的问题,及解决办法...

中所周知,Java中的泛型并不像C++、C#一样是真正的泛型,其泛型是通过类型擦除来实现的。具体什么是类型擦除,可以参看这篇博文:http://icyfenix.iteye.com/blog/1021949。今天要记录的是在实际开发中遇到的一个,由于Java这种泛型的实现方式而导致的问题,及解决办法。

一下代码是模拟真实开发环境下的实现:

1 @Test2 public voidtest(){3 //构建searchMap,模拟前端传来的查询参数

4 Map searchMap = new HashMap();5 List goodsIds1 = new ArrayList();6 goodsIds1.add(1);7 goodsIds1.add(2);8 goodsIds1.add(3);9 searchMap.put("goodsIds", goodsIds1);10 searchMap.put("goodsType", 1);11

12 //利用searchMap进行查询,模拟后端的逻辑

13 List goodsIds2 = (List)searchMap.get("goodsIds");14 for(Long goodsId : goodsIds2){15 System.out.println(goodsId);16 }17 }

这里的searchMap用来接收前端传来的查询商品信息的参数,假设要查询商品id分别为1、2、3,同时商品类型为1的商品。后端逻辑会从searchMap中获取goodsIds的list,然后循环查询每一个商品的信息。以上代码在eclipse中不会提示任何错误,但其实在运行的时候会抛出  java.lang.ClassCastException 异常。

问题就在于第9行

searchMap.put("goodsIds", goodsIds1);

中goodsIds1是List 类型的,而第13行

List goodsIds2 = (List)searchMap.get("goodsIds");

在取出goodsIds的时候,虽然强制转换为List型,但实质上,goodsIds2中的值为Integer型,如下图:

b0646b34a55f9c001b32cee4ce25ac25.png

所以在第14行遍历goodsIds2的时候

for(Long goodsId : goodsIds2){

System.out.println(goodsId);

}

就会抛出 java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long 异常。这里本质就是由于List和List,在编译之后,其泛型信息都被擦除,都被视为List,所以取出时能够转换成功。

其实在第13行,IDE会给出警告:Type safety: Unchecked cast from Object to List,虽然可以通过在方法上加注解:@SuppressWarnings("unchecked")来消除警告,但这只是起到标示作用,并不会修正错误。最简单的修复的办法就是将goodsIds2也声明为List,然后再遍历的时候转为Long型,但是不太优雅。另外一种解决方法就是,用Java类去接收前端传来的参数,而不是用Map,但是这样的话需要增加一个POJO类。那为什么不直接将goodsIds1也声明为List型呢?像这样:

1 @Test2 public voidgenericTest(){3 //构建searchMap,模拟前端传来的查询参数

4 Map searchMap = new HashMap();5 List goodsIds1 = new ArrayList();6 goodsIds1.add(1L);7 goodsIds1.add(2L);8 goodsIds1.add(3L);9 searchMap.put("goodsIds", goodsIds1);10 searchMap.put("goodsName", "商品1");11

12 //利用searchMap进行查询,模拟后端的逻辑

13 List goodsIds2 = (List)searchMap.get("goodsIds");14 for(Long goodsId : goodsIds2){15 System.out.println(goodsId);16 }17 }

这样做确实能够通过测试,但在实际开发中,用Map去接收到的参数,当数值小于Integer的最大值时,会默认将其按Integer处理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值