中所周知,Java中的泛型并不像C++、C#一样是真正的泛型,其泛型是通过类型擦除来实现的。具体什么是类型擦除,可以参看这篇博文:http://icyfenix.iteye.com/blog/1021949。今天要记录的是在实际开发中遇到的一个,由于Java这种泛型的实现方式而导致的问题,及解决办法。
一下代码是模拟真实开发环境下的实现:
1 @Test 2 public void test(){ 3 // 构建searchMap,模拟前端传来的查询参数 4 MapsearchMap = 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
ListgoodsIds2 = (List )searchMap.get("goodsIds");
在取出goodsIds的时候,虽然强制转换为List
所以在第14行遍历goodsIds2的时候
for(Long goodsId : goodsIds2){ System.out.println(goodsId); }
就会抛出 java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long 异常。这里本质就是由于List
其实在第13行,IDE会给出警告:Type safety: Unchecked cast from Object to List
1 @Test 2 public void genericTest(){ 3 // 构建searchMap,模拟前端传来的查询参数 4 MapsearchMap = 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