Atea - Hero's Grave

面向对象,开源,框架,敏捷,云计算,NoSQL,商业智能,编程思想。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  40 随笔 :: 0 文章 :: 28 评论 :: 0 Trackbacks
JDK1.5引入的泛型,减少了类型强转的代码,增加了编译检查,提高了代码的健壮性。
但在某些情况,泛型检查会出乎意料的“丢失”,由此可引发难以发现的bug。
 1 public class GenericDefectTest {
 2 
 3     public void test(final Map<String, String> map) {
 4         System.out.println(map.get("a"));// 这行可以正常执行
 5         System.out.println(map.get("b"));// 运行到这行才会报错
 6         for (Map.Entry<String, String> entry : map.entrySet()) {
 7             System.out.println(entry.getValue());
 8         }
 9     }
10 
11     public static void main(final String args[]) throws Exception {
12         GenericDefectTest genericTest = new GenericDefectTest();
13 
14         Map<String, Object> map = new HashMap<String, Object>();
15         map.put("a""a");
16         map.put("b"1);
17         // new GenericTest().test(map);// 这里有编译验证,如果取消注释会出错。没有问题
18 
19         // 但是如果用反射调用的话,就没有验证了,在实际使用这个值的时候才会报错
20         Method test = GenericDefectTest.class.getDeclaredMethod("test", Map.class);
21         test.invoke(genericTest, map);
22     }
23 }
我们期望程序执行到第三行就会报错,但实际进行到第五行才会报错。

反编译查看class
 1 public class GenericDefectTest
 2 {
 3   public void test(Map<String, String> map)
 4   {
 5     System.out.println((String)map.get("a"));
 6     System.out.println((String)map.get("b"));
 7     for (Map.Entry entry : map.entrySet())
 8       System.out.println((String)entry.getValue());
 9   }
10 
11   public static void main(String[] args) throws Exception
12   {
13     GenericDefectTest genericTest = new GenericDefectTest();
14 
15     Map map = new HashMap();
16     map.put("a""a");
17     map.put("b", Integer.valueOf(1));
18 
19     Method test = GenericDefectTest.class.getDeclaredMethod("test"new Class[] { Map.class });
20     test.invoke(genericTest, new Object[] { map });
21   }
22 }
可以看到泛型仍然存在于函数定义中。

这可以说是一个Java泛型的"缺陷",实际使用中需要特别注意。
posted on 2011-05-31 10:31 Atea 阅读(674) 评论(0)  编辑  收藏 所属分类: Java language

只有注册用户登录后才能发表评论。


网站导航: