黑马程序员技术交流社区

标题: 关于反射跳过泛型编译的问题..求教~~~ [打印本页]

作者: wahaha    时间: 2013-3-3 16:52
标题: 关于反射跳过泛型编译的问题..求教~~~
本帖最后由 夏添 于 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")吗?

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

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


作者: 折纸时代    时间: 2013-3-3 18:24
java的泛型只在编译时期有效.  也就是说在字节码内部是没有泛型限定了.
所以反射通过字节码来跳过泛型的限定.

字节码是编译后的数据,已经没有限定了.  所以此时任由你如何添加任何类型的数据. 就和没有限定是一样的.
作者: wahaha    时间: 2013-3-3 20:33
司懿卓 发表于 2013-3-3 18:24
java的泛型只在编译时期有效.  也就是说在字节码内部是没有泛型限定了.
所以反射通过字节码来跳过泛型的限 ...

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

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

但是(反射)有了钥匙后,把门打开了,就可以放任意能放进去的物品了..
作者: 余勇    时间: 2013-3-4 17:56
学习了,明白了,




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