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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 毕仁杰 黑马帝   /  2011-8-8 00:17  /  2422 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

下面的这段代码正常,可以通过反射将泛型中只能存储类型变量为Integer的集合中存储字符串,并将字符串输出。[code=java]package cn.csdn.day2;

import java.util.ArrayList;

public class GenericTest1 {

        public static void main(String[] args) throws Exception{
                ArrayList<Integer> alist = new ArrayList<Integer>();
               
                //通过反射将只能存储类型变量为Integer的集合中存储字符串
                alist.getClass().getMethod("add", Object.class).invoke(alist, "abc");
                System.out.println(alist.get(0));
        }
}[/code]但是,反过来,看下面的一段代码[code=java]package cn.csdn.day2;

import java.util.ArrayList;

public class GenericTest1 {

        public static void main(String[] args) throws Exception{
                ArrayList<String> alist = new ArrayList<String>();
                alist.getClass().getMethod("add", Object.class).invoke(alist, new Integer(123));
                System.out.println(alist.get(0));
        }

}[/code]错误信息为:[code=java]Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        at cn.csdn.day2.GenericTest1.main(GenericTest1.java:10)[/code]还是提示需要强制转化,这是为什么?

3 个回复

倒序浏览
黑马网友  发表于 2011-8-8 01:22:30
沙发
:lol 你太聪明了 想到这样子的问题
回复 使用道具 举报
黑马网友  发表于 2011-8-8 02:00:25
藤椅
一开始我也不知道原因的,但测试了不同的类,查找方法,最后终于找到了一个比较合理的解释。请看代码:[code=java]package heima.answer;


import java.util.ArrayList;

public class Test5 {

         public static void main(String[] args) throws Exception{
       
//下面是:case1       
                 
                 
//         ArrayList<Integer> alist = new ArrayList<Integer>();
//         
//         //通过反射将只能存储类型变量为Integer的集合中存储字符串
//         alist.getClass().getMethod("add", Object.class).invoke(alist, "abc");
//         System.out.println(alist.get(0));//输出 :abc
//         System.out.println(alist.get(0).TYPE); //运行到该步时抛出如下异常:
//         //Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
   
                 
                 
     //下面是:case2
                 ArrayList<String> aList = new ArrayList<String>();//经测试发现,只有当泛型结合中装的是String时,比较奇怪一些,而其他基本数据类型的包装类不会发生类型转换异常
                 aList.getClass().getMethod("add",Object.class).invoke(aList,"abc");
                 aList.getClass().getMethod("add",Object.class).invoke(aList,123);
                 
                 System.out.println(aList.get(0));//正常输出abc
                 System.out.println(aList.get(1));//抛出类型转换异常
                 
                 /*上面的打印输出如下:
         Exception in thread "main" abc
                java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
                at heima.answer.Test5.main(Test5.java:23)
         */
                 
                 
                 System.out.println(aList.get(1).TYPE);
                 /*这个语句报错了,说明语句通不够编译器。证明了String类没有枚举常量Sting.TYPE,
                  *
                 case2中的 System.out.println(aList.get(1)); 与 case2中的 System.out.println(aList.get(1).TYPE);这两个语句执行结果一样,说明
                 了打印String的时候,会自动对比该打印的类型是否是String类型,而Integer等类型因为有枚举常量TYPE,所以不会自动对比所打印的类型,但当我们调用它的类型时候,系统会
                 抛出异常,因为系统已经知道了你要打印的是Integer类型的数据,而你通过反射传入泛型集合的是String类型的数据(见case1),二者不统一,所以报错。
                 
                 
         */
                 
                 
                 /**
                  * 经查API发现,基本数据的包装类都有TYPE字段,表示的是该类的一个实例。而String类则没有TYPE。
                  *
                  字段摘要
static int MAX_VALUE
          值为 231-1 的常量,它表示 int 类型能够表示的最大值。
static int MIN_VALUE
          值为 -231 的常量,它表示 int 类型能够表示的最小值。
static int SIZE
          用来以二进制补码形式表示 int 值的比特位数。
static Class<Integer> TYPE
          表示基本类型 int 的 Class 实例。

                  *
                  *
(下面是TYPE的定义)                 
TYPE
public static final Class<Integer> TYPE表示基本类型 int 的 Class 实例。

从以下版本开始:
JDK1.1
                  *
                  *
                  */
                 
}


}[/code][color=Red]欢迎其他童鞋继续探讨该题,我给出的只是一个参考的答案,也许是错的,欢迎你推翻我的推理。[/color]
回复 使用道具 举报
黑马网友  发表于 2011-8-8 02:03:08
板凳
手机看不到代码,弱弱的问句,反射不是要先把类加载进虚拟机吗,加载后泛型不是被擦除了吗,哪来的结合
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马