通过Class,Method来认识泛型的本质
packagecom.reflect;importjava.lang.reflect.Method;importjava.util.ArrayList;public classMethodDemo2 {public static void main(String[] args) throwsException
{
ArrayList list=newArrayList();
ArrayList list1=new ArrayList();
list1.add("hello");//list1.add(10);//会因为10不是String类型而出错
Class c1=list.getClass();
Class c2=list1.getClass();
System.out.println(c1==c2);//反射的操作都是编译之后的操作
/** C1==C2结果返回true,说明编译后集合的泛型是去泛型化的
* Java中,集合的泛型,是防止错误输入的,只在编译阶段有效
* 绕过编译就无效了
* 验证:我们可以通过方法的反射来操作,绕过编译
**/Method m=c1.getMethod("add", Object.class);
m.invoke(list1,1);
System.out.println(list1.size());
System.out.println(list1);//此时不能用这种方式遍历了,因为之前已经插入了int类型的,这样会转化为String类型,会转换错误
for(String str:list1)
{
System.out.println(str);
}
}
}
运行结果:
分析上诉结果:
1,list和list1都能add加入集合String类型变量,但是list1由于使用了泛型,所以限定只能加入String类型的,而不能加入Int类型的,但是list没有使用泛型,所以
可以加入任意类型变量。使用泛型的作用就是为了防止输入了错误类型的变量。
2,list1不能加入int类型的变量,是因为编译时候,进行了校验,但是反射是在编译后进行的操作,因此可以绕过编译
3,因为c1==c2,说明list1和list是同一种类类型,都是ArrayList类的类类型。
4,因为泛型绕过了编译,所以使用泛型调用方法的时候,即使使用的是list1集合对象,依然可以插入int类型的变量。
5,list1对象插入了int类型的变量后,不能使用foreach方式输出了,因为此时是通过编译的方式,需要进行int到String类型的转型,显然会报错。