在java中,当代码进行编译时会进行去泛型化,所以如果我们可以绕过泛型,在编译和运行时将对某个泛型化的对象进行修改就不会报错。下面举个例子说明,
如何利用java的反射机制来绕过java的泛型化。
package javaReflect;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class genericReflect {
// 泛型编程过程中,在定义时指定的类型只是为了防止输入上的错误,但是在编译阶段就没有了类型的限制
// 在使用反射时可以绕过泛型的限制,下面来举个例子
public static void main(String[] args) throws Exception {
// 新建一个没有指明类型的list
ArrayList list = new ArrayList();
list.add("stirng test");
// 新建一个指明类型的list
ArrayList<String> StringList = new ArrayList<String>();
StringList.add("string");
Class c1 = list.getClass();
Class c2 = StringList.getClass();
System.out.println(c1.getName() + " " + c2.getName());
// 这里的输出为真,说明泛型不会影响实际的类型,它的实际类型就是ArrayList,也说明编译之后集合
// 的泛型是去泛型化的
System.out.println(c1 == c2);
//获取ArrayList的add函数
Method m = c2.getMethod("add", Object.class);
// StringList本来的泛型本来是String类型的,正常情况下用add添加整数是会报错的,但是通过反射机制,
// 是在运行时添加进去的,已经去去泛型化le
//这样可以执行,不会报错
m.invoke(StringList, 100);
/*这样会报错
StringList.add(100);
*/
/*
* 这里直接输出没有问题,但是如果用foreach输出就会出现异常,因为类型不一样 //ava.lang.Integer cannot be
* cast to java.lang.String for (String string : StringList) {
* System.out.println(string); }
*/
System.out.println(StringList);
}
}
利用java反射机制绕开java的泛型
最新推荐文章于 2022-08-23 14:19:38 发布