黑马程序员技术交流社区

标题: 怎样通过反射获取成员变量的泛型? [打印本页]

作者: 黑马_许芸    时间: 2012-8-27 23:00
标题: 怎样通过反射获取成员变量的泛型?
早晨看到某位仁兄的帖子而开始思考这个问题。结果一天过去了,也没弄出来。而他的帖子也沉得找不到了,所以再问一次。
问题一:下面程序,类ListDemo中定义了一个成员变量 List<String> array 。怎样通过反射的获取到array的泛型String?
问题二:Field类中的getGenericType这个方法是干嘛用的?
  1. package practise;

  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Type;
  4. import java.util.ArrayList;
  5. import java.util.Iterator;
  6. import java.util.List;

  7. class  ListDemo
  8. {
  9.          private List<String> array = new ArrayList<String>();
  10.          
  11.          public void setArray()
  12.                 {
  13.                  array.add("林青霞");
  14.              array.add("齐秦");
  15.              array.add("齐豫");
  16.              array.add("大S");
  17.                 }
  18. }

  19. class MainClass
  20. {
  21.          public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
  22.         {
  23.                  ListDemo ld = new ListDemo();
  24.          ld.setArray();
  25.                  
  26.          Class<?> clszz = ld.getClass();
  27.          Field filed = clszz.getDeclaredField("array");
  28.          filed.setAccessible(true);
  29.          
  30. //         Type type = filed.getGenericType();
  31.          
  32.          ArrayList arrayList = (ArrayList)filed.get(ld);
  33.          for(Iterator iterator = arrayList.iterator();iterator.hasNext();)
  34.          {
  35.                  System.out.println(iterator.next());
  36.          }
  37.         }
  38. }
复制代码
程序运行结果:
林青霞
齐秦
齐豫
大S



作者: 刘芮铭    时间: 2012-8-28 00:19
(1)得到这个类中的指定的方法
  Method method = ListDemo.class.getDeclaredMethod("setArray", ArrayList.class);
(2)得到该方法的泛型的{参数化类型}类ParameterizedType
  Type [] types = method.getGenericParameterTypes();
  ParameterizedType pType = (ParameterizedType) types[0];
(3)分别得到该参数化类型的原始类型和实际类型pType.getRawType();
pType.getActualTypeArguments()[0];

  
通过查阅API文档可以:
Field类中的getGenericType:
返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型。

作者: 唐见    时间: 2012-8-28 00:43
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class  ListDemo
{
         private List<String> array = new ArrayList<String>();
         private List<Integer> intg=new ArrayList<Integer>();//另外加上的,测试用
         public void setArray(){
             array.add("林青霞");
             array.add("齐秦");
             array.add("齐豫");
             array.add("大S");
             intg.add(123);
             intg.add(32);
         }
}
class MainClass
{
         public static void main(String[] args) throws Exception
        {
             ListDemo ld = new ListDemo();
             ld.setArray();
                 Class clszz = ld.getClass();
                 Field filed = clszz.getDeclaredField("array");
                 Field filed1 = clszz.getDeclaredField("intg");
                 filed.setAccessible(true);
//                 Type type = filed.getGenericType();
                 //在这里解释getGenericType方法的作用和如何获取参数化类型对象的类型参数(楼主说的泛型)
                 //为了方便解释和测试,将获取类型参数名封装成方法printParamName
                 System.out.println("array表示的类型参数:");
                 printParamName(filed);//打印array表示的类型参数及String
                 System.out.println("intg表示的类型参数:");
                 printParamName(filed1);//打印intg表示的类型参数Integer                
                 ArrayList arrayList = (ArrayList)filed.get(ld);
                 for(Iterator iterator = arrayList.iterator();iterator.hasNext();)
                 {
                         System.out.println(iterator.next());
                 }
        }
        /**
         * 获取参数化类型的属性对象的参数类型
         * @param field        表示类属性成员的参数化对象
         */
        public static void printParamName(Field field){
                Type type = field.getGenericType();
                //getGenericType方法的作用
                //返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型。如果 Type 是一个参数化类型,则返回的 Type 对象必须准确地反映源代码中使用的实际类型参数。
                //如果底层字段的类型是一个类型变量或者是一个参数化类型,则创建它。否则将解析它。
                //在看Type类:Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
                ParameterizedType pType=(ParameterizedType)type;
                //我们已经知道type这里表示的是参数化类型接口,所有将type强制转换成ParameterizedType
                //ParameterizedType 表示参数化类型,如 Collection<String>。
                //参数化类型在反射方法首次需要时创建(在此包中指定)。当创建参数化类型 p 时,p 实例化的一般类型声明会被解析,并且按递归方式创建 p 的所有类型参数。
                System.out.println(pType.getActualTypeArguments()[0]);//返回带参数化类型的参数类型,即String,参数类型也可能有多个,这里只有一个,所有取第1个参数
                //Type[] getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。
                //注意,在某些情况下,返回的数组为空。如果此类型表示嵌套在参数化类型中的非参数化类型,则会发生这种情况。
        }
}
/*打印结果
array表示的类型参数:
class java.lang.String
intg表示的类型参数:
class java.lang.Integer
林青霞
齐秦
齐豫
大S
*/






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2