Java泛型反射,java泛反射,泛型技术主要应用在编译时
分享于 点击 10804 次 点评:208
Java泛型反射,java泛反射,泛型技术主要应用在编译时
泛型技术主要应用在编译时期。在编译时期,编译器负责参数类型的检测,到了运行时期,即生成了字节码后,所包含的泛型定义的类型信息就不存在了(或说被擦除了),这就是泛型的类型擦除,在生成的字节码中无类型信息,这也是虚拟机的局限性导致的。
import java.util.ArrayList; public class GenericDemo { public static void main(String[] args) { //泛型类型为String ArrayList<String> at1 = newArrayList<String>(); //泛型类型为Integer ArrayList<Integer>at2 = newArrayList<Integer>(); //运行结果为true,说明都是同一份字节码,已擦除了泛型类型了 System.out.println(at1.getClass() ==at2.getClass()); } }
泛型是针对编译器的,通过反射可以绕过编译器对泛型类型的检查:
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class ReflectDemo{ public static void main(String ... args) throws Exception{ test_1(); //test_2(); } private static void test_2(){ //未使用泛型限制,虽然元素都能存储和取出,但是安全性却大大降低了! List list = new ArrayList(); list.add("string ..."); list.add(123); list.add(true); Object o1 = list.get(0); Object o2 = list.get(1); Object o3 = list.get(2); System.out.println(o1); System.out.println(o2); System.out.println(o3); } private static void test_1() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { //使用泛型限制了元素类型 List<String> list = new ArrayList<String>(); Class clazz = list.getClass(); System.out.println(clazz.getName()); //使用反射绕开编译器 Method method = clazz.getMethod("add", Object.class); method.invoke(list, new Integer(20)); //这里的get函数,编译器认为取出的是String类型 Object o = list.get(0); System.out.println(o); } }
通配符<?>
和写具体泛型参数<E>有的不同:
通配符?不能进行具体对象的操作,即不能调用与参数化有关的方法,因为?是不确定的类型,不具备对象,只能用些跟对象无关的方法,如集合的ArrayList原始类型的size()方法,与集合元素类型无关。
而泛型参数E是有对象的,可进行具体的对象的操作,是种限定类型, 如迭代器输出时,可以E e = it.next();而后对e进行对象操作。也可进行(E)”abc”;之类的强制转换。
另外,在泛型结构的内部也要使用泛型参数时,就需定义泛型参数E了。
参数化类型不考虑继承关系:
Vector<String> v = new Vector<Object>(); ×Vector<Object> v = new Vector<String>(); ×Vector v = new Vector<String>();Vector<Object> v1 = v; //这两句能顺利编译通过
通过反射获取泛型的参数化类型:
importjava.lang.reflect.Method; import java.lang.reflect.ParameterizedType; importjava.lang.reflect.Type; importjava.util.Date; importjava.util.Vector; public class GenericReflect { public static voidmain(String[] args) throws Exception { //获取fun方法 Method method =GenericReflect.class.getMethod("fun", Vector.class); //Type类型是Calss的父类,Method类中提供了获取泛型参数的方法 Type[] types =method.getGenericParameterTypes(); // ParameterizedType是Type的子类 ParameterizedTypepType = (ParameterizedType)types[0]; //获取泛型的原始类型 System.out.println(pType.getRawType()); //获取泛型的参数变量 System.out.println(pType.getActualTypeArguments()[0]); } public static voidfun(Vector<Date> vd) { } }
用户点评