黑马程序员技术交流社区

标题: 关于反射和泛型的 [打印本页]

作者: 向前看向前走    时间: 2014-5-18 20:22
标题: 关于反射和泛型的
本帖最后由 向前看向前走 于 2014-5-19 09:41 编辑

        ArrayList<String> arraylist = new ArrayList<String>();
               
               
                arraylist.getClass().getMethod("add",Object.class).invoke(arraylist, new Integer(12));
                System.out.println(arraylist.get(0));

这一段代码是关于反射的,会报错,有谁能讲一下原理,和为什么报错!

               
作者: 多一点    时间: 2014-5-18 20:27
ArrayList<String> arraylist = new ArrayList<String>();泛型类型是String  你传进一个Iteger的对象怎么可以呢传一个String  对象就好了

arraylist.getClass().getMethod("add",Object.class).invoke(arraylist, new String("123"));
作者: 向前看向前走    时间: 2014-5-18 20:40
多一点 发表于 2014-5-18 20:27
ArrayList arraylist = new ArrayList();泛型类型是String  你传进一个Iteger的对象怎么可以呢传一个Strin ...

呃。当定义一个Integer通过反射传String是可以的,我就是想问一下反过来怎么就不行,还是条件不对!还有为什么在运行的时候没有泛型的痕迹,这个泛型转化为了什么呢?
作者: 多一点    时间: 2014-5-18 20:57
向前看向前走 发表于 2014-5-18 20:40
呃。当定义一个Integer通过反射传String是可以的,我就是想问一下反过来怎么就不行,还是条件不对!还有 ...

还真的不行
作者: 多一点    时间: 2014-5-18 21:01
多一点 发表于 2014-5-18 20:57
还真的不行

会不会是Integer 能转String ,String就转不来Integer,随便想的
作者: 向前看向前走    时间: 2014-5-18 21:23
多一点 发表于 2014-5-18 21:01
会不会是Integer 能转String ,String就转不来Integer,随便想的

泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,再调用其add方法即可。
    我看到张孝祥老师写的这一段话,明白了转为什么了,既然转为了原始,怎么就数值类型就放入不进去了呢?原始的应该是什么类型都可以放入吧!有人了解这一段没
作者: 梦幻精灵    时间: 2014-5-18 21:24
学习一下。。。。。。。。。。。。。。
作者: 向前看向前走    时间: 2014-5-18 21:51
自己又根据实际应用自定义一个类,发现这样又是可以的,看来还是String 有点特殊
ArrayList<Auto> auto = new ArrayList<Auto>();
                auto.add(new Auto());
                auto.getClass().getMethod("add", Object.class).invoke(auto, 3);
                System.out.println(auto.get(1));

class Auto
{
        //private String name="zhangsan";
       
}

这样子就没有报错,这个特殊点在那里呢
作者: skill20    时间: 2014-5-18 23:03
本帖最后由 skill20 于 2014-5-18 23:16 编辑

有试过分开来写吗?个人建议。这个是我的实现方式。
  1. public static void get()throws Exception{
  2.                 List<String> list = new ArrayList<String>();
  3.                 list.add("a");
  4.                 list.add("b");
  5.                 list.add("c");
  6.                 Class clazz = list.getClass();
  7.                 Method method = clazz.getMethod("add", Object.class);
  8.                 method.invoke(list,new Integer(12));
  9.                 Method method_1 = clazz.getMethod("get",int.class);
  10.                 Object obj = method_1.invoke(list,3);
  11.                 System.out.println(obj);
  12.         }
复制代码





作者: 多一点    时间: 2014-5-18 23:40
向前看向前走 发表于 2014-5-18 21:23
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编 ...

我再去发个帖子问问
作者: 向前看向前走    时间: 2014-5-19 02:29
skill20 发表于 2014-5-18 23:03
有试过分开来写吗?个人建议。这个是我的实现方式。

看了你的代码,受了启发,问题在于这一句:System.out.println(arraylist.get(0))
发现当值为数值的时候,会去向字符串去转,如果返回是类就不会
List<String> arraylist = new ArrayList<String>();
                       
                arraylist.getClass().getMethod("add",Object.class).invoke(arraylist,1 );
            Object a= arraylist.get(0);
                System.out.println(a);
这样子就不会有问题,我推测是,Java默认是对字符串这种类型,如果检查到输出是字符串的,会值类型向字符串转化,应该是内部有这一处理机制,而字符串不会默认向值类型转变。
不知道这一推测对不,不过也是知道问题所在了。


作者: alax    时间: 2014-5-19 04:49
泛型是指明了  ArrayList集合中要存放的对象类型 若存的不是String类型 编译时会出错 如不用泛型 这个错误会在运行时报错




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