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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wahaha 中级黑马   /  2013-3-3 16:52  /  1800 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 夏添 于 2013-3-4 21:22 编辑

关于反射跳过泛型编译的问题..
看张老的视屏,泛型的那段中,说反射可以跳过编译期,具体例子见下面代码.
弱弱的问下:虚拟机编译到底在编译神马?或者说检查神马??不要说检查语法哈..这个筒子们都晓得..

ArrayList<Integer> collection3 = new ArrayList<Integer>();

collection3.getClass().getMethod("add",object.class).invoke(collection3,"abc");

System.out.println(collection3.get(0));
编译运行结果是abc,泛型貌似不起作用,泛型是编译过程给虚拟机看的,请问,在编译过程中
虚拟机不能检测出*.invoke(collection3,"abc")吗?

看张老说的,也是晕晕的哈,求解释哈~~~

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

7 个回复

倒序浏览
编译在编译带类型信息的集合是会去掉类型信息的,是程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值,和原始类型完全一样
ArrayList<Integer> collection2= new ArrayList<Integer>();
ArrayList<String> collection3 = new ArrayList<String>();
System.out.println(collection2.getClass()== collection3.getClass());这里返回的是true
因为编译成的字节码会去掉类型的类型信息,所以通过反射得到集合,就可以同add方法向集合里面添加各种不同类型的数据

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

回复 使用道具 举报
java的泛型只在编译时期有效.  也就是说在字节码内部是没有泛型限定了.
所以反射通过字节码来跳过泛型的限定.

字节码是编译后的数据,已经没有限定了.  所以此时任由你如何添加任何类型的数据. 就和没有限定是一样的.

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

回复 使用道具 举报
司懿卓 发表于 2013-3-3 18:24
java的泛型只在编译时期有效.  也就是说在字节码内部是没有泛型限定了.
所以反射通过字节码来跳过泛型的限 ...

额,我似乎明白了,就好比说你偷了辆车没钥匙打不开,逆向反求得到图纸,再复制一台汽车出来,这个新汽车是没有钥匙的,是吧,呵呵,
回复 使用道具 举报
泛型实在编译时,毕老师视频里说的好,将可能出现的错误交给程序员处理而不是用户,编译过后泛型的类型信息就不存在了。反射是在运行时,Class.forName("ArrayListr").getMethod("add",Object.Class).invoke(new ArrayList(),"abc")这句代码执行即add(new ArrayList(),"abc")是在运行时。Java的泛型就写代码的时候有用,比较坑爹
回复 使用道具 举报
夏添 发表于 2013-3-3 20:33
额,我似乎明白了,就好比说你偷了辆车没钥匙打不开,逆向反求得到图纸,再复制一台汽车出来,这个新汽车是没 ...

不能这么说. 应该是该房间没有钥匙的情况下, 只能放入指定类型的东西.  如果小物件..  因为门洞小,算是限定.

但是(反射)有了钥匙后,把门打开了,就可以放任意能放进去的物品了..
回复 使用道具 举报
余勇 来自手机 中级黑马 2013-3-4 17:56:38
7#
学习了,明白了,
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马