欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java泛型反射,java泛反射,泛型技术主要应用在编译时

来源: javaer 分享于  点击 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)         {         }    }    
相关栏目:

用户点评