黑马程序员技术交流社区

标题: 通过反射向泛型集合添加不同类型元素时遇到的问题 [打印本页]

作者: 上官睿鹏    时间: 2014-3-21 16:03
标题: 通过反射向泛型集合添加不同类型元素时遇到的问题
本帖最后由 上官睿鹏 于 2014-3-21 22:07 编辑

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;


class Demo
{
           public static void main(String[] args)throws Exception
           {
                   List<Integer> list = new ArrayList<Integer>();
                   //list.add("abc");//编译器会报错,下面通过反射绕过编译器向里面添加String类型元素
                   list.getClass().getMethod("add", Object.class).invoke(list, "abc"); //通过反射向集合里添加String类型数据
                   System.out.println(list.get(0));           //这里可以顺利打印出字符串
           }
}
但是下面这样就不行了,不知道是啥原。
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;


public class Demo {
           public static void main(String[] args) throws Exception {
                    List<String> list = new ArrayList<String>();
                    //list.add(1);//编译器会报错,下面通过反射绕过编译器向里面添加Integer类型元素
                    list.getClass().getMethod("add", Object.class).invoke(list, 1); //通过反射向集合里添加Integer类型数据

                    System.out.println(list.size());              //到这里程序能够打印出结果为1
                    System.out.println(list.get(0));          //这句话就报错了(ClassCastException),按理应该不报啊,上面的程序都能打印出结果
           }        
}
























作者: 乔钰博    时间: 2014-3-21 17:01
本帖最后由 乔钰博 于 2014-3-21 17:28 编辑

因为编译器在编译List<String> list = new ArrayList<String>();的时候会把泛型去掉,你可以试试
List<String> list = new ArrayList<String>();
List<Integer> list0 = new ArrayList<Integer>();
list.getClass() == list0.getClass();
输出的结果是true,也就是说两者用的是同一个字节码文件,也就验证了我说的编译是去掉泛型的,所以反射获取了字节码文件然后创建了一个新的对象是不带泛型,所以什么类型的数据都能往里面添加
但是如果通过get方法想把一个Integer类型的数据从泛型为String的ArrayList从取出,会报错,是因为你取数据的时候,会自动进行类型转换,而Integer类型的无法转成String型,就报错了。
自动转型是JDK1.5泛型的新特性,1.5之前都是要手动转型的。
作者: syusikoku    时间: 2014-3-21 17:17
贴上我的代码,希望能帮的上你
ArrayList<String> coll = new ArrayList<String>();
  coll.add("abc");
  coll.add("dff");
  coll.add("hqr");
  System.out.println(coll);
  
  //绕过编译器向集合中添加其它类型的元素
  Method addMethod=coll.getClass().getMethod("add",Object.class);
  addMethod.invoke(coll, 23);
  System.out.println(coll);
  System.out.println(coll.get(0));

作者: 上官睿鹏    时间: 2014-3-21 17:40
本帖最后由 上官睿鹏 于 2014-3-21 17:43 编辑
乔钰博 发表于 2014-3-21 17:01
因为编译器在编译List list = new ArrayList();的时候会把泛型去掉,你可以试试
List list = new ArrayList ...

我贴的第一个程序通过get方法把一个String类型的数据从泛型为Integer的ArrayList取出,为什么就不会报错啊?可以打印出abc啊




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