黑马程序员技术交流社区

标题: 泛型--运行期,利用反射为集合添加其他类型元素,取出出... [打印本页]

作者: 黄锦成    时间: 2012-12-27 10:54
标题: 泛型--运行期,利用反射为集合添加其他类型元素,取出出...
本帖最后由 黄锦成 于 2012-12-29 22:51 编辑

//-----------------------第二段代码报了异常-----------------------------
  ArrayList<Integer> collection = new ArrayList<Integer>();
  collection.add(1);
  collection.add(2);
  //利用反射,在运行期添加一个String元素
  Method add = collection.getClass().getMethod("add", Object.class);
//往只能存Integer的ArrayList中,利用反射存入String,取出String不会出现ClassCastException
  add.invoke(collection, "this is");
  System.out.println(collection.get(2));
  
  
ArrayList<String> collection1 = new ArrayList<String>();
  collection1.add("java01");
  collection1.add("java02");
  //利用反射,在运行期添加一个Integer元素
  Method add1 = collection1.getClass().getMethod("add", Object.class);
  //往只能存String的ArrayList中,利用反射存入Integer,取出Integer时出现ClassCastException
  add1.invoke(collection1, 100);
  System.out.println(collection1.get(2));//提示我这行错了

第二段代码我是拷贝第一段的代码,然后修改了一下类型,变量名
同样是反射在运行期往ArrayList中添加其他类型的元素,在第一段代码不报ClassCastException,成功取出
而在第二段代码中,却出现了ClassCastException错误提示如下
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

作者: 马志军    时间: 2012-12-27 12:24
本帖最后由 马志军 于 2012-12-27 12:27 编辑

ClassCastException当试图将对象强制转换为不是实例的子类时,抛出该异常。
API里这么说的。发现变成System.out.println((Object)collection1.get(2));就能打印出来了。
看到篇博客说,当将某一对象强制转换为某一子类时,如果该对象并非该子类的实例,JVM就会抛出ClassCastException异常。
add方法接收参数是Object的,相当于Object obj=new Integer(100)放到集合中。
文档说 Object x = new Integer(0);
     System.out.println((String)x);
这种情况就是错误的
可能意思是将Object对象强制转换为子类String对象,但new Integer(100)并非是String类实例,所以抛异常。
作者: 黄锦成    时间: 2012-12-27 12:33
马志军 发表于 2012-12-27 12:24
ClassCastException当试图将对象强制转换为不是实例的子类时,抛出该异常。
API里这么说的。发现变成System ...


按照你的解释,那我还有个问题:第一段代码那里,我在ArrayList<Integer> collection = new ArrayList<Integer>();中添加了一个元素"this is",String不是Integer的子类,那他取出"this"为什么不报类型转换异常

作者: 马志军    时间: 2012-12-27 12:56
我也有点猜,不是太明白
第一个添加this is 相当于Object obj=new String("this is");
打印的时候变成字符串,但Object对象,那个new String("this is")本来就是String类实例,所以没异常。
作者: 黄锦成    时间: 2012-12-27 13:02
马志军 发表于 2012-12-27 12:56
我也有点猜,不是太明白
第一个添加this is 相当于Object obj=new String("this is");
打印的时候变成字符 ...

println()方法有多个重载方式,打印时,不用类型转换。还是没解决我的疑惑
作者: 陈琦    时间: 2012-12-27 13:29
System.out.println(collection.get(2));这句调用的是toString()方法,你collection设定的泛型是Integer,Integer可以通过toString()转换成String,而collection1里设定的泛型是String,你存的是Integer,String要想转换成Interger对象,必须使用Integer.parseInt()或valueOf()进行转换。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2