黑马程序员技术交流社区

标题: 关于反射获得泛型的参数化类型 [打印本页]

作者: 李挺    时间: 2013-2-26 18:16
标题: 关于反射获得泛型的参数化类型
在张老师的通过反射获得泛型的参数化类型那一个例子中
  1. public class GenericTest {

  2. /**
  3.   * @param args
  4.   */
  5. public static void main(String[] args) throws Exception {
  6.   GenericDao<ReflectPoint> dao = new GenericDao<ReflectPoint>();
  7.   dao.add(new ReflectPoint(3,3));  
  8.   //String s = dao.findById(1);
  9.   
  10.   //Vector<Date> v1 = new Vector<Date>();
  11.   Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class);//获取方法
  12.   Type[] types = applyMethod.getGenericParameterTypes(); //获取泛型
  13.   ParameterizedType pType = (ParameterizedType)types[0];
  14.   System.out.println(pType.getRawType());
  15.   System.out.println(pType.getActualTypeArguments()[0]);
  16. }

  17. public static void applyVector(Vector<Date> v1){  //主要是通过这个方法
  18.   
  19. }
  20. }
复制代码
注意到这句Type[] types = applyMethod.getGenericParameterTypes();
这句话返回的是type数组
我查了一下API
说:Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。 这个type到底是什么呢?




作者: 李挺    时间: 2013-2-26 22:04
type啊type
作者: Benwolf0818    时间: 2013-2-26 22:09
因为同一个类的构造函数可能有多个.它们可以根据不同的调用参数来区分.所以这里需要你告诉它你要寻找的构造函数是有多少个参数的,每个参数是什么类型.Type[]里面的元素个数就是参数数目,每个Type代表第几个参数是什么类型的
作者: 李挺    时间: 2013-2-26 22:16
崔芝鲁 发表于 2013-2-26 22:09
因为同一个类的构造函数可能有多个.它们可以根据不同的调用参数来区分.所以这里需要你告诉它你要寻找的构造 ...

能从方法上得到构造函数?
作者: 王钊    时间: 2013-2-27 17:44
这只是一个面向对象多态与面向接口编程的体现而已,实际上types收到的是Type这个接口的子接口类型元素,
api文档上写着Type有四个子接口GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType。
其实下面再强制转换时,用instanceof判断一下是否是PrameterizedType会更好,更安全,这里张老师显然已经知道types[0]是什么,所以就免去了判断。
举个例子,这个会更好。
  1. import java.lang.reflect.Field;
  2. import java.lang.reflect.ParameterizedType;
  3. import java.lang.reflect.Type;
  4. import java.util.Map;

  5. public class GenericTest
  6. {
  7.         private Map<String, Integer> score;

  8.         public static void main(String[] args) throws Exception
  9.         {
  10.                 Class<GenericTest> clazz = GenericTest.class;
  11.                 Field f = clazz.getDeclaredField("score");
  12.                 // 直接使用getType()取出Field类型只对普通类型的Field有效
  13.                 Class<?> a = f.getType();
  14.                 // 下面将看到仅输出java.util.Map
  15.                 System.out.println("score的类型是:" + a);
  16.                 // 获得Field实例f的泛型类型
  17.                 Type gType = f.getGenericType();//注意这里要用顶层接口Type接收,因为方法定义就是这样的
  18.                 // 如果gType类型是ParameterizedType对象
  19.                 if (gType instanceof ParameterizedType)
  20.                 {
  21.                         // 强制类型转换
  22.                         ParameterizedType pType = (ParameterizedType) gType;
  23.                         // 获取原始类型
  24.                         Type rType = pType.getRawType();
  25.                         System.out.println("原始类型是:" + rType);
  26.                         // 取得泛型类型的泛型参数
  27.                         Type[] tArgs = pType.getActualTypeArguments();
  28.                         System.out.println("泛型类型是:");
  29.                         for (int i = 0; i < tArgs.length; i++)
  30.                         {
  31.                                 System.out.println("第" + i + "个泛型类型是:" + tArgs[i]);
  32.                         }
  33.                 }
  34.                 else
  35.                 {
  36.                         System.out.println("获取泛型类型出错!");
  37.                 }
  38.         }
  39. }
复制代码





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