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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王运科 中级黑马   /  2012-4-8 10:31  /  3573 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

        List<Integer> l1=new ArrayList<Integer>();
        l1.getClass().getMethod("add",Object.class).invoke(l1, 23);
        l1.getClass().getMethod("add",Object.class).invoke(l1, "abc");

getMethod方法里面("add",Object.class),为什么要用Object.class,而不能用Integer.class或者String.class,这个表示什么意思啊?本人看了JDK6.0有关内容,很可惜没有看懂。

5 个回复

倒序浏览
一个程序要运行他必须经过编译阶段(javac.*.java),运行阶段(java *).
javac 可以将你的代码生成.class文件,也就是把你写得代码翻译成计算机认识的字节码。编译器在对你的代码进行编译的时候就会检查语法错误,明明指定好了只能添加Integer类型的数据,你怎么能往里边塞String 呢?
但是泛型只在编译的时候起作用,在运行阶段(java *)的时候,你得ArrayList已经不受泛型的控制了。也就是说跟普通的ArrayList已经没有区别。通过反射方法获得的Method本身就是字节码无需编译就能加进去。
回复 使用道具 举报
按照我的理解应该是这样,Integer和String类型都是Object的子类,既然你的getMethod方法里面("add",Object.class)放的是Object.class那么现在不管是Integer.class还是String.class也好,放进去都没有问题,如果你把Object.class改成Integer.class的话
当你放String.class的时候就会产生错误。
回复 使用道具 举报
泛型是1.5以后提供的。
ArrayList<>中的泛型,在编译完了之后,去掉了类型信息,
invoke方法属于字节码身上的,与对象无关。
因为是用反射的方法,直接从字节码中拿到方法添加元素,所以,绕过了<>泛型的限制,结果就可以把原来需要接受Integer
对象的集合加入了一个String对象,并把它打印出来了。
从这个角度,泛型可以说只是给编译器看到,编译完后,泛型信息就被去除了,字节码中已经没有泛型的痕迹。
回复 使用道具 举报
本帖最后由 贠(yun)靖 于 2012-4-8 13:43 编辑

l1.getClass().getMethod("add",Object.class).invoke(l1, 23);
l1.getClass().getMethod("add",Object.class).invoke(l1, "abc");
getMethod  是获得  方法的字节码对象 , “” 引号中字符串表示具体哪个方法的对象      Object。class  是因为add方法的参数是Object类型的
因为集合中可以添加任意对象  所以就得是object作为参数了
invoke 是Method类中的方法,  可以理解为  让Method对象和传进参数的那个对象  建立关系,使之操作确定的那个方法具体属于参数对象的   

在反射中要时刻知道  每个具体的变量  方法 构造方法 等等 都是一个类    得到这个类的对象后   再确定这个变量 或方法  或构造方法  是属于那个具体实体对象的 就哦了
回复 使用道具 举报
 楼主的PP实在是写得太好了。照片线条流畅,布局得体,且楼主的气质中深得古人遗风,更将唐风宋骨发扬得入木三分,儒雅张扬激情!能在有生之年看见楼主的这个PP。实在是我三生之幸啊。看完楼主的这个帖子之后,我竟感发生出一种无以名之的悲痛感――啊,这么好的帖,如果将来我再也看不到了,那我该怎么办?那我该怎么办?直到我毫不忧郁的把楼主的这个帖子收藏了。我内心的那种激动才逐渐平复下来。可是我立刻想到,这么好的帖子,倘若别人看不到,那么不是浪费楼主的心血吗?经过痛苦的思想斗争,我终于下定决心,我要把这个帖子一直往上顶,往上顶!顶到所有人都看到为止!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马