• 使用反射为泛型集合添加其他类型的数据时遇到的问题


    泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合进会去掉“类型”信息,使程序运行效率不受影响。

    由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合虽加入其它类型的数据。
    所以我们可以用反射为泛型集合添加其他类型的数据。
     
    例1:
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
      arrayList .add(10);
      arrayList .add(20);
      arrayList .getClass().getMethod("add",Object.class).invoke(arrayList ,"hbase");
      System.out.println(arrayList .get(2));//虽然索引为2的位置存的是String类型,但编译时编译器会认为arrayList .get(2)返回的时是Integer类型,但在运行取值时取的仍是                                         //String类型
    输出:hbase
     
    例2:
    ArrayList<String> arrayList = new ArrayList<String>();
      arrayList1.add("hadopp");
      arrayList1.add("hive");
      arrayList1.getClass().getMethod("add",Object.class).invoke(arrayList1,25);
      System.out.println(arrayList1.get(2));//虽然索引为2的位置存的是Integer类型,但编译时编译器会认为arrayList .get(2)返回的时是String类型,但在运行取值时取的仍                                       //Integer类型
    
    
    报错!!
    Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
     at com.mobin.generic.GenericTest.main(GenericTest.java:20)
    报错代码:System.out.println(arrayList1.get(2));
    Integer不能转成String,但例1为会又不报ClassCastException异常呢?(大家也可以先想想原因是什么再看下面的分析)
     
     
     
    下面分析下原因:
    出现ClassCastException这个异常可以断定的是类型的转换错误。
    原因就在Syststem.out.println这条语句,
    上图是println()的所有重载方法,除了bool,char,char[],double,float,int,String,long类型外,当传入的参数是其他类型时被会被当作是Object从而调用println(Object)方法。
    在例1中由于arrayList1.get(2)返回的是Integer所以调用的是println(Object)方法,验证:把鼠标放到println方法上即可.
    好,我们再进入println(Object x)的源码去看看
    参数都被自动的转成了String类型!!!
    相当于Object x = arrayList.get(2);   //所有对象都属于Object
             String s = String.valueOf(x);
    所以不会报错。
     
     
    再看第二段代码的println调用的是println(String x);
    同样进入源码去看看:
    相当于String x = arrayList.get(2);      //这里运行时arrayList.get(2)所得的值的类型是Integer,又相当于String x = Integer;所以才报错
     
  • 相关阅读:
    asp.net 2.0 treeview控件“简单”操纵
    http://www.cnblogs.com/Terrylee/archive/2006/11/12/aspnet_ajax_quickstarts.html(ajax入门 )
    JS实面treeview中选中父节点,子节点也选中
    系统地学习ASP.NET AJAX(5) 客户端脚本编程(Sys.UI命名空间下的类和快捷方法)(转)
    图例显示投标数据
    怎么用正则表达式判断数字(包括正,负,小数。。)
    treeview常见用法
    TreeView小结
    sql split分隔
    WCF 漫谈
  • 原文地址:https://www.cnblogs.com/MOBIN/p/4773603.html
Copyright © 2020-2023  润新知