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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 代臣 黑马帝   /  2012-4-26 17:20  /  2785 人查看  /  6 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

public class GenericTest {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                //为什么把String改为Integer之后,在invoke中传入字符串类型的参数就能行呢?
                //具体代码见下面的单行注释
                ArrayList<String> collection = new ArrayList<String>();
                //ArrayList<Integer> collection = new ArrayList<Integer>();
               
                try {
                        collection.getClass().getMethod("add", Object.class).invoke(collection, 2);
                        //collection.getClass().getMethod("add", Object.class).invoke(collection, "abc");
                        //将上面的代码都换成单行注释的代码之后运行有结果,为什么用没注释的代码情况下编译通不过。
                        //为什么报java.lang.Integer cannot be cast to java.lang.String异常。
                        //而在加注释代码情况下却不报java.lang.String cannot be cast to java.lang.Integer异常?
                        System.out.println(collection.get(0));
                       
                } catch (IllegalArgumentException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (SecurityException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (IllegalAccessException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (InvocationTargetException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (NoSuchMethodException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }
}

6 个回复

倒序浏览
找了半会了,昨天看到了,实验了下。确实是这样的。所以研究了下。
ClassCastException异常:
当试图将对象强制转换为不是实例的子类时,抛出该异常。例如,以下代码将生成一个 ClassCastException:
     Object x = new Integer(0);
     System.out.println((String)x);

用反射调用方法时,指定方法名是add,方法参数是Object.class  之后传入的是个Integer,输出的时候也就是
System.out.println();这句话是吧所有类型都转换成String类型打印出来,就做了如上异常动作:
     Object x = new Integer(0);
     System.out.println((String)x);
实验取出元素后打印,遍历集合元素。定义取出来的元素类型为String的话,同样会报ClassCastException异常
如异常动作。
代码:
        for(String s:collection)
                {
                        System.out.println(s);
                }

所以定义元素类型为Object这样就没有执行异常动作了。
for(Object s:collection)
                {
                        System.out.println(s);
                }


这样不用加注释,泛型为String也一样,无异常
回复 使用道具 举报
上面回复有漏洞,想了差不多1个小时我还是没想明白,不想了,想不通,如果照上面说的话,应该定义<Integer>也是不行的.忽忽,
分析有3点,打印输出语句,异常为1.0版本的,泛型和自动装箱时1.5的,不过知识有限,弄不明白,
有明白的同学请说下。。这问题够想的。
回复 使用道具 举报
本帖最后由 邵中国 于 2012-4-27 18:39 编辑

{:soso_e134:}
回复 使用道具 举报
回复 使用道具 举报
本帖最后由 黑马我来了 于 2012-4-28 07:29 编辑
  1. public static void main(String[] args) {

  2.         ArrayList<String> collection = new ArrayList<String>();
  3.        //   ArrayList<Integer> collection = new ArrayList<Integer>();
  4.   
  5.         
  6.        try {
  7.                 collection.getClass().getMethod("add", Object.class).invoke(collection,2);
  8.                 //collection.getClass().getMethod("add", Object.class).invoke(collection,"abc");
  9.                 System.out.println((Object)collection.get(0));//这里强制转一下就可以取出来了
  10.          
  11.                
  12.        } catch (IllegalArgumentException e) {
  13.                 // TODO Auto-generated catch block
  14.                 e.printStackTrace();
  15.         } catch (SecurityException e) {
  16.                 // TODO Auto-generated catch block
  17.                 e.printStackTrace();
  18.         } catch (IllegalAccessException e) {
  19.                 // TODO Auto-generated catch block
  20.                 e.printStackTrace();
  21.         } catch (InvocationTargetException e) {
  22.                 // TODO Auto-generated catch block
  23.                 e.printStackTrace();
  24.         } catch (NoSuchMethodException e) {
  25.                 // TODO Auto-generated catch block
  26.                 e.printStackTrace();
  27.         }

  28.         }
复制代码
ArrayList<String> collection = new ArrayList<String>(); 泛型String里面可以放int的数据,关键是看你怎么取值。楼主的错误,是报在System.out.println(collection.get(0));取值这行,这里需要强制转换下。 楼主看一下是不是你需要的结果,如果不是的话,请指出一下。

回复 使用道具 举报
代臣 黑马帝 2012-4-29 17:20:23
7#
邓斌 发表于 2012-4-27 13:56
上面回复有漏洞,想了差不多1个小时我还是没想明白,不想了,想不通,如果照上面说的话,应该定义也是不行 ...

辛苦了,这个问题是有点麻烦,张老师在讲的时候说编译的时候会去掉泛型限定,看了下PPT,然后就试试是不是这样的,一试就试出上面的问题。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马