黑马程序员技术交流社区

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

作者: 伍淑江    时间: 2013-4-24 18:39
标题: 关于反射和泛型的问题?
本帖最后由 伍淑江 于 2013-4-26 22:44 编辑

List<String> list =new ArrayList<String>
如何用反射在List集合中添加一个Integer值?

作者: 何俊森    时间: 2013-4-26 09:07
本帖最后由 何俊森 于 2013-4-26 09:19 编辑

如果只是为了限定它是为Integer类型的话,可以这样,见代码:
  1. import java.lang.reflect.Method;
  2. import java.util.ArrayList;
  3. import java.util.List;


  4. public class RefectTest3 {
  5.     public static void main(String[] args) throws InstantiationException, Exception {
  6.         // TODO Auto-generated method stub
  7.         List<Integer> list = new ArrayList<Integer>();   //其中这行的Integer可以为任意类型,因为编译器编译带泛型的集合后会手插掉泛型信息,因此下面设置方法参数类型要是Object
  8.         Method met = list.getClass().getMethod("add",Object.class); //设置方法参数类型
  9.         met.invoke(list,new Integer(12));
  10.         met.invoke(list,new Integer(23));
  11.         met.invoke(list,new Integer(45));
  12.         System.out.println(list);
  13.     }
  14. }

复制代码

作者: 曹睿翔    时间: 2013-4-26 09:26
何俊森 发表于 2013-4-26 09:07
如果只是为了限定它是为Integer类型的话,可以这样,见代码:

楼主意思是泛型的意义在于限定集合中元素的属性,提高安全性,有时可以省去强转动作。
泛型编译后就,没了
通过反射(暴力),可以向本来存String的集合中添加Integer。
请再贴代码
作者: 何俊森    时间: 2013-4-26 09:54
曹睿翔 发表于 2013-4-26 09:26
楼主意思是泛型的意义在于限定集合中元素的属性,提高安全性,有时可以省去强转动作。
泛型编译后就,没 ...
  1. import java.lang.reflect.Method;
  2. import java.util.ArrayList;
  3. import java.util.List;


  4. public class RefectTest3 {
  5.         public static void main(String[] args) throws InstantiationException, Exception {
  6.                 // TODO Auto-generated method stub
  7.                 List<String> list = new ArrayList<String>();
  8.                 Method met = list.getClass().getMethod("add",Object.class); //设置方法参数类型
  9.                 met.invoke(list,"dsf");
  10.                 met.invoke(list,23);
  11.                 met.invoke(list,45.0f);
  12.                 System.out.println(list);
  13.                 //System.out.println(list.get(1)); //取出的时候出错 java.lang.ClassCastException
  14.         }
  15. }
复制代码
这样没有什么意义,String的集合添加了 Integer了,但是要调用带泛型的方法出错。
作者: 袁梦希    时间: 2013-4-26 09:58
本帖最后由 袁梦希 于 2013-4-26 09:59 编辑

楼主你好,
其实这道题,指的是泛型类型只在编译时期有效果,当在运行时期就自动去掉了。
所以我们可以在运行时期利用反射插入一个Integer类型的值。
我给你写了段代码和详细的注释,你看看能不能帮到你。
  1. package com.xbox.test;

  2. import java.lang.reflect.Method;
  3. import java.util.ArrayList;
  4. /*
  5. * 第二题:ArrayList<Integer> list = new ArrayList<Integer>();
  6. * 在这个泛型为Integer的ArrayList中存放一个String类型的对象。
  7. */
  8. public class Test {
  9. //这里我们为了代码好看,就把异常抛出了
  10. public static void main(String[] args) throws Exception {

  11. ArrayList<String> list = new ArrayList<String>();

  12. list.add("abc");//这里添加的String类型的数据,没问题,
  13. // list.add(123); //如果这里添加Integer,编译会报错,所以我们可以用反射,在运行时添加数字

  14. /*
  15. *注意如果获取方法的时候如果参数类型为String.class,说明已经限定了String类型
  16. *所以换成Object类型
  17. *Method method = list.getClass().getMethod("add",String.class);
  18. */

  19. //获取对象的字节码调用其方法,返回其方法对象。
  20. Method method = list.getClass().getMethod("add",
  21. Object.class);

  22. //这里调用的是字符串
  23. method.invoke(list,"123");//插入Integer对象
  24. //method.invoke(list,123);//这里貌似不能自动装箱

  25. System.out.println(list.get(0));
  26. System.out.println(list.get(1));//打印出了Integer
  27. }

  28. }
复制代码

作者: 刘凯    时间: 2013-4-26 09:59
一句话,这个张孝祥老师基础加强视频上有详细讲解的,仔细看视频就好了
作者: 曹睿翔    时间: 2013-4-26 10:57
袁梦希 发表于 2013-4-26 09:58
楼主你好,
其实这道题,指的是泛型类型只在编译时期有效果,当在运行时期就自动去掉了。
所以我们可以在运 ...

肿么办,你抢别人饭碗啊,哈哈
不过问题解决了
作者: 袁梦希    时间: 2013-4-26 11:03
曹睿翔 发表于 2013-4-26 10:57
肿么办,你抢别人饭碗啊,哈哈
不过问题解决了

热心帮助云丝们,再苦点再累都没啥,有时候觉得云丝们很可爱:lol
作者: 何俊森    时间: 2013-4-26 12:19
袁梦希 发表于 2013-4-26 11:03
热心帮助云丝们,再苦点再累都没啥,有时候觉得云丝们很可爱

大神,这是我的一点补充,不知道对不对?

QQ截图20130426120808.png (52.13 KB, 下载次数: 40)

QQ截图20130426120808.png

作者: 袁梦希    时间: 2013-4-26 14:03
何俊森 发表于 2013-4-26 12:19
大神,这是我的一点补充,不知道对不对?

不用管我叫大神,都是同一级别的。我来给你解释一下。
一.
Method method = list.getClass().getMethod("add", Object.class);
这段代码以前我用Integer.class测试过,没出现异常,今天我测试了,总出现异常。
可能是集合可以接收任意对象的原因,所以用Object。

二.
  method.invoke(list, new Integer(123));
  method.invoke(list, new Long(123));
  method.invoke(list, 123);//自动装箱
  
  System.out.println(list);

  //这里忘记说了,虽然说插入数据可以插入,但是获取数据的时候还要判断泛型
  //因为几个中1角标的位置是Integer对象。所以获取数据的时候应该是String对象
  //  System.out.println(list.get(1));所以这里在获取数据的时候会抛异常


作者: 何俊森    时间: 2013-4-26 14:07
{:soso_e181:}学习了。。
作者: 何俊森    时间: 2013-4-26 14:09
袁梦希 发表于 2013-4-26 14:03
不用管我叫大神,都是同一级别的。我来给你解释一下。
一.
Method method = list.getClass().getMethod(" ...

{:soso_e181:}




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