A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 向前看向前走 中级黑马   /  2014-5-18 20:22  /  2120 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 向前看向前走 于 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));

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

               

11 个回复

倒序浏览
ArrayList<String> arraylist = new ArrayList<String>();泛型类型是String  你传进一个Iteger的对象怎么可以呢传一个String  对象就好了

arraylist.getClass().getMethod("add",Object.class).invoke(arraylist, new String("123"));
回复 使用道具 举报
多一点 发表于 2014-5-18 20:27
ArrayList arraylist = new ArrayList();泛型类型是String  你传进一个Iteger的对象怎么可以呢传一个Strin ...

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

还真的不行
回复 使用道具 举报

会不会是Integer 能转String ,String就转不来Integer,随便想的
回复 使用道具 举报
多一点 发表于 2014-5-18 21:01
会不会是Integer 能转String ,String就转不来Integer,随便想的

泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,再调用其add方法即可。
    我看到张孝祥老师写的这一段话,明白了转为什么了,既然转为了原始,怎么就数值类型就放入不进去了呢?原始的应该是什么类型都可以放入吧!有人了解这一段没
回复 使用道具 举报
学习一下。。。。。。。。。。。。。。
回复 使用道具 举报
自己又根据实际应用自定义一个类,发现这样又是可以的,看来还是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: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 21:23
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编 ...

我再去发个帖子问问
回复 使用道具 举报
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默认是对字符串这种类型,如果检查到输出是字符串的,会值类型向字符串转化,应该是内部有这一处理机制,而字符串不会默认向值类型转变。
不知道这一推测对不,不过也是知道问题所在了。

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

回复 使用道具 举报
alax 中级黑马 2014-5-19 04:49:08
12#
泛型是指明了  ArrayList集合中要存放的对象类型 若存的不是String类型 编译时会出错 如不用泛型 这个错误会在运行时报错
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马