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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 林其荣 中级黑马   /  2013-1-13 18:11  /  2144 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

张孝祥老师讲的一个泛型的知识点时,碰到了一个问题,张老师说泛型只是给编译器看的,以张老师举的例子说明:
都是ArrayList类型的对象,一个是String型(ArrayList<String>)arr1,另一个是Integer型(ArrayList<Integer>)arr2,这两个对象在编译完成后生成的字节码是相同的,利用反射调用add方法时应该可以把泛型屏蔽的,但是我碰到了下面的问题,代码如下:
  1.   ArrayList<Integer> arr1 = new ArrayList<Integer>();
  2.          arr1.getClass().getMethod("add", Object.class).invoke(arr1, "abc");
  3.          System.out.println(arr1.get(0));
复制代码
上面这个没有问题,可以把泛型屏蔽掉,但是下面的却不行:
  1. ArrayList<String> arr2 = new ArrayList<String>();
  2.          arr2.getClass().getMethod("add", Object.class).invoke(arr2, 2);
  3.          System.out.println(arr2.get(0));
复制代码
运行报了异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        at day1.GenericTest.main(GenericTest.java:34)


不知道为什么,String型的可以屏蔽,Integer的却不行

评分

参与人数 1黑马币 +9 收起 理由
黄锦成 + 9

查看全部评分

11 个回复

倒序浏览
这个问题我也问过,但是还没解决
回复 使用道具 举报
错误原因是由于你的System.out.println(arr2.get(0));

改成这样就正常OK了
ArrayList<String> arr2 = new ArrayList<String>();
              arr2.getClass().getMethod("add", Object.class).invoke(arr2, 2);
              System.out.println(String.valueOf(arr2.get(0)));
回复 使用道具 举报
Rancho_Gump 来自手机 高级黑马 2013-1-13 19:13:12
板凳
正好看到这
回复 使用道具 举报
Rancho_Gump 来自手机 高级黑马 2013-1-13 19:18:46
报纸
手机上的看不到代码  我估摸着可能和自动装拆箱有关吧
回复 使用道具 举报
类的转换异常,包转型类型Integer 与 String 转换产生异常,解决方式:采用泛型上限与下限 转换就ok了
注意,第一个程序容器方的是Integer 所以没问题 而第二个程序容器放的是 String,System.out.println(arr2.get(0)) 打印的值是 Integer与容器String类型不符,
所以产生类转换异常错误,改成 Integer.toString(arr2.get[0])即可
ClassCastException 新手最容易犯着错误,自己注意下
回复 使用道具 举报
王阳 中级黑马 2013-1-13 20:42:21
7#
赵文 发表于 2013-1-13 19:23
类的转换异常,包转型类型Integer 与 String 转换产生异常,解决方式:采用泛型上限与下限 转换就ok了
注意 ...

感觉你的方法说不通。因为这样的话,那么怎么解释第一个呢? 可是在Integer里保存String类型。一样存在类型转换问题,个人认为不仅仅是类型转换的问题。
回复 使用道具 举报
jonn 高级黑马 2013-1-13 20:53:41
8#


不是类转换异常么?
回复 使用道具 举报
jonn 高级黑马 2013-1-13 20:55:44
9#
王阳 发表于 2013-1-13 20:42
感觉你的方法说不通。因为这样的话,那么怎么解释第一个呢? 可是在Integer里保存String类型。一样存在类 ...

间接利用反射调用泛型类型,但还是要依据容器数据类型一致,错误产生异常难道不是ClassCastException 类转换异常.....
回复 使用道具 举报
赵文 发表于 2013-1-13 20:55
间接利用反射调用泛型类型,但还是要依据容器数据类型一致,错误产生异常难道不是ClassCastException 类 ...

错误虽然是转换异常,但是我意思是,为什么前一个可以而后一个不可以呢。。。?这个才是问题。因为一旦运行起来泛型就被擦除了的。。为什么还会有类型转换异常,这个就是我想问的
回复 使用道具 举报
看了下源码,println(x) 如果x是String,则是直接打印x,如果x是其他类型,则打印String.valueOf(x),
因为arr2被添加了String泛型,所以编译时就会认为x是String类型,不会再使用调用String.valueOf(x)的那个println(x)方法,
但是运行时取出的是Integer,所以出现类型转换异常
回复 使用道具 举报
楼上正解,你把最后一个输出语句换成:
System.out.println(String.valueOf(arr2.get(0)));
或者:
for(Iterator it = arr2.iterator(); it.hasNext();){
                                System.out.println(it.next());
                        }
就没问题了,关键就是这个方法println()内部工作机制。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马