绕过编译器对泛型list添加泛型规定外的类型元素.
泛型只在 编译阶段 有效.
反射的操作都是编译之后的操作。
如图中带范式和不带范式的list取类类型的结果相同,说明编译之后结合的范式是去泛型化的。
Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了。
验证:如图可以通过方法的反射来操作,绕过编译,实现在一个ArrayList <string>中add加入一个数字20
注意:但是现在不能再使用for遍历数。组了,否则会报类型错误。
List无论是否加入<范式>,其类类型都是一样。
如图中,代码结果为true
泛型,编译阶段有效
反射的操作,Class的操作、Method的操作等都是绕过编译的。
java集合的泛型是为了防止输入类型错误的,但只在编译阶段有效。
333333333333
2222222222222222222
22222222222222
111111111111111111
mark .
反射的操作都是编译之后的操作
反射的操作时编译之后的操作
两个不同对象
Array list =new ArrayList();
Array<String> list2 =new ArrayList<String>(); //使用泛型约束
Class c1=list.getClass();
Class c2=list2.getClass();
c1==c2结果返回true说明编译之后集合泛型是去泛型化的
Java中集合的泛型,是防止输入错误,只在编译阶段有效
绕过编译就无效了
利用方法反射来操作,绕过编译
java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了
总结:反射可以绕过编译
泛型的本质:编译之后的泛型是去泛型化的
Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了
验证,我们可以通过方法的反射操作,绕过编译,绕过编译操作就绕过了泛型
动态代理中,要执行某个类的方法时,先生成该类的代理类,通过代理类去调用目标类的方法,从而可以在代理类中执行 额外的逻辑。为了动态生成代理类,而不事先生成,我们就需要利用到反射。
反射的操作都是编译之后的操作
Java通过反射了解集合泛型的本质
知识点1:通过Class,Method认识泛型的本质,反射的操作都是编译之后的操作。
集合泛型:防止错误输入的,只在编译阶段有效,编译之后该泛型就无效了。
如果对一个集合使用String泛型,那么添加20,就会出错,通过创建两个ArrayList对象,一个加泛型,一个不加泛型,结果验证加泛型的类类型和不加泛型的类类型是相等的。
结论:c1==c2结果返回true,说明编译之后集合的泛型是去泛型化的。
案例:通过方法的反射来操作,绕过编译,往集合中添加其他类型数据。
先了解java反射,因为动态代理中,用到反射,具体如下:
动态代理中,要执行某个类的方法时,先生成该类的代理类,通过代理类去调用目标类的方法,从而可以在代理类中执行 额外的逻辑。为了动态生成代理类,而不事先生成,我们就需要利用到反射。
绕过编译就等于绕过泛型。
反射可以绕过编译
绕过编译操作就绕过了泛型?!
Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了!
4)通过Class,Method来认识泛型的本质
什么是泛型?泛型什么时候有效?
六、通过反射了解集合泛型的本质
1、通过Class和Method了解泛型的本质
2、Java集合中的泛型,是防止错误输入的,只在编译阶段有效,绕过编译机无效了
ArrayList list1 = new ArrayList();
ArrayList<String> list2 = new ArrayList<String>();
Class c1 = list1.getClass();
Class c2 = list2.getClass();
System.out.Println(c1 == c2);
打印出true,说明编译后集合的泛型是去泛型化的
3、验证
我们可以通过方法的反射来操作,绕过编译
Method m = c1.getMethod("add",Object.class);
m.invoke(list2,100);//绕过编译操作就绕过了泛型
System.out.println(list2.size());
打印出1,说明加进去了
此时就不能用foreach来遍历了,否则会报类型转换异常