public static void main(String[] args) {
//告诉编译器我这个集合只能存储String类型的
List col=new ArrayList();
//告诉编译器我这个集合只能存储Integer类型的
List<Integer> col2=new ArrayList<Integer>();
//输出结果为:true
//这就是常说的去除,编译后jvm虚拟机不会知道这个集合存储什么类型的值
System.out.println(col.getClass()==col2.getClass());
//看我如何将String存储到集合col2中。
/**
* 在运行过程中,jvm根本不知道col2应该存放什么类型的数据,只是我们在编译器中限定了。
* 我们通过反射可以获取list的add方法给col2存储其他类型的数据。如这里就可以将“abc”存放到col2中
* 不明白这里为什么参数一定要是Object.class,不能改为String.class
*/
try {
col2.getClass().getMethod("add", Object.class).invoke(col2, "abc");
System.out.println(col2.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();
}
}
为什么这里必须是Object.class了,list里的add是泛型啊。col2.getClass().getMethod("add", Object.class)
list里的add是泛型,然后Object.class就确实类型了啊,它是一个基类
因为擦除的原因,泛型只有编译器知道,对于JVM来说只知道list
你要是参数改成String.class就通不过编译了吧
都说了泛型是给编译器看的,所以在编译器编译完成之后实际的class里面是Object