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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 HM朱蛟 于 2013-5-28 11:49 编辑

老师的例子结果没问题:

package cn.itcast.day2;
import java.util.*;
public class GenericDemo {
/**
  * @param args
  */
public static void main(String[] args)throws Exception {
  ArrayList<Integer> collection = new ArrayList<Integer>();
  //collection.add(1);//集合泛型限定是Integer然而我却想通过反射的方式给他add一个字符串
  collection.getClass().getMethod("add", Object.class).invoke(collection,"abc");
  collection.add(2);
  System.out.println(collection.get(0)+" and "+collection.get(1));
}
}

输出结果:
abc and 2


我把泛型限定类型改了下,Integer改成String然后反射进一个Integer,同样的操作方式这里要抛出异常,类型转换失败。
  1. import java.util.*;

  2. public class GenericDemo {

  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args)throws Exception {

  7. ArrayList<String> collection = new ArrayList<String>();
  8. //collection.add(1);//集合泛型限定是String然而我却想通过反射的方式给他add一个整数
  9. collection.getClass().getMethod("add", Object.class).invoke(collection,new Integer(1));
  10. //collection.add("abc");
  11. System.out.println(collection.get(0)+" and "+collection.get(1));
  12. }
  13. }
复制代码
运行结果:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at cn.itcast.day2.GenericDemo.main(GenericDemo.java:16)

7 个回复

倒序浏览
不懂,我用了先编译后在反编译一下,虽然不同的源文件可以生成一样的.class文件,但是这些源文件实现了相同的功能。
  1. package cn.itcast.day2;

  2. import java.io.PrintStream;
  3. import java.lang.reflect.Method;
  4. import java.util.ArrayList;

  5. public class GenericDemoTest01
  6. {
  7.   public static void main(String[] paramArrayOfString)
  8.     throws Exception
  9.   {
  10.     ArrayList localArrayList = new ArrayList();

  11.     localArrayList.getClass().getMethod("add", new Class[] { Object.class }).invoke(localArrayList, new Object[] { "abc" });
  12.     localArrayList.add(Integer.valueOf(2));
  13.     System.out.println(localArrayList.get(0) + " and " + localArrayList.get(1));
  14.   }
  15. }
复制代码
以下出错的反编译的java文件
  1. package cn.itcast.day2;

  2. import java.io.PrintStream;
  3. import java.lang.reflect.Method;
  4. import java.util.ArrayList;

  5. public class GenericDemoTest02
  6. {
  7.   public static void main(String[] paramArrayOfString)
  8.     throws Exception
  9.   {
  10.     ArrayList localArrayList = new ArrayList();

  11.     localArrayList.getClass().getMethod("add", new Class[] { Object.class }).invoke(localArrayList, new Object[] { new Integer(1) });
  12. localArrayList.add("abc");
  13.     System.out.println((String)localArrayList.get(0) + " and " + (String)localArrayList.get(1));
  14.   }
  15. }
复制代码
可以发现localArrayList.get(0) 取出来会强制转化为String类型((String)localArrayList.get(0)),所以会出现java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String。
楼主可以试试在泛化类型的时候,ArrayList<任意类型> localArrayList = new ArrayList<任意类型>(),在用反射添加String类型的数值,然后get()出来打印都是不会出错的。

回复 使用道具 举报
如果楼主想加技术分,请看我下面的个性签名↓
回复 使用道具 举报
游客 182.135.113.x 发表于 2013-5-24 13:31
谢谢斑竹 也不是想加技术分 就是像想决下问题  这里上论坛上的少 所以没注意就发到这里来了 ...

恩没事 ,只要注册一下就好了:)
回复 使用道具 举报
lz可以试试将collection.get()的结果用Object接受一下再打印就可以了
原理就在于泛型和printIn方法,你的例1中由于泛型的原因,编译器认为ArrayList中存的都是Integer所以 collection.get()出来的认为是Integer类型
而io包中printStream类中有众多printIn方法,其中就有printIn(Object  obj)和 printIn(String  s),
编译阶段System.out.printIn(collection.get()),
其中的collection.get()就告诉打印方法打印的是Integer对象所以就会调用printIn(Object  obj)来接受,当collection出来是String而不是Integer时也可以接受并打印出来,因为Object可以接受String嘛
所以你例2中当泛型是String时,编译阶段就告诉打印方法打印的String类型,而打印方法刚好有接受String的printIn(String s)方法,所以运行阶段调用的是
printIn(String s),当collection.get()取出元素的是Integer并打印就会出错了。
回复 使用道具 举报
q5486555 发表于 2013-5-26 23:50
lz可以试试将collection.get()的结果用Object接受一下再打印就可以了
原理就在于泛型和printIn方法,你的例 ...

高见 谢谢
回复 使用道具 举报
何俊森 发表于 2013-5-23 20:27
不懂,我用了先编译后在反编译一下,虽然不同的源文件可以生成一样的.class文件,但是这些源文件实现了相同 ...

高见 谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马