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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 上官睿鹏 于 2014-3-21 22:07 编辑

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;


class Demo
{
           public static void main(String[] args)throws Exception
           {
                   List<Integer> list = new ArrayList<Integer>();
                   //list.add("abc");//编译器会报错,下面通过反射绕过编译器向里面添加String类型元素
                   list.getClass().getMethod("add", Object.class).invoke(list, "abc"); //通过反射向集合里添加String类型数据
                   System.out.println(list.get(0));           //这里可以顺利打印出字符串
           }
}
但是下面这样就不行了,不知道是啥原。
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;


public class Demo {
           public static void main(String[] args) throws Exception {
                    List<String> list = new ArrayList<String>();
                    //list.add(1);//编译器会报错,下面通过反射绕过编译器向里面添加Integer类型元素
                    list.getClass().getMethod("add", Object.class).invoke(list, 1); //通过反射向集合里添加Integer类型数据

                    System.out.println(list.size());              //到这里程序能够打印出结果为1
                    System.out.println(list.get(0));          //这句话就报错了(ClassCastException),按理应该不报啊,上面的程序都能打印出结果
           }        
}























3 个回复

正序浏览
本帖最后由 上官睿鹏 于 2014-3-21 17:43 编辑
乔钰博 发表于 2014-3-21 17:01
因为编译器在编译List list = new ArrayList();的时候会把泛型去掉,你可以试试
List list = new ArrayList ...

我贴的第一个程序通过get方法把一个String类型的数据从泛型为Integer的ArrayList取出,为什么就不会报错啊?可以打印出abc啊
回复 使用道具 举报
贴上我的代码,希望能帮的上你
ArrayList<String> coll = new ArrayList<String>();
  coll.add("abc");
  coll.add("dff");
  coll.add("hqr");
  System.out.println(coll);
  
  //绕过编译器向集合中添加其它类型的元素
  Method addMethod=coll.getClass().getMethod("add",Object.class);
  addMethod.invoke(coll, 23);
  System.out.println(coll);
  System.out.println(coll.get(0));
回复 使用道具 举报
本帖最后由 乔钰博 于 2014-3-21 17:28 编辑

因为编译器在编译List<String> list = new ArrayList<String>();的时候会把泛型去掉,你可以试试
List<String> list = new ArrayList<String>();
List<Integer> list0 = new ArrayList<Integer>();
list.getClass() == list0.getClass();
输出的结果是true,也就是说两者用的是同一个字节码文件,也就验证了我说的编译是去掉泛型的,所以反射获取了字节码文件然后创建了一个新的对象是不带泛型,所以什么类型的数据都能往里面添加
但是如果通过get方法想把一个Integer类型的数据从泛型为String的ArrayList从取出,会报错,是因为你取数据的时候,会自动进行类型转换,而Integer类型的无法转成String型,就报错了。
自动转型是JDK1.5泛型的新特性,1.5之前都是要手动转型的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马