黑马程序员--Java基础加强--16.利用反射操作泛型V【通过Constructor反射解析泛型构造方法】【通过Field反射解析泛型成员变量】【个人总结】
2013-08-10 10:10
1391 查看
利用反射操作泛型IV
通过Constructor反射解析泛型构造方法 通过Field反射解析泛型成员变量
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------1. 通过Constructor反射解析泛型构造方法
1). 构造方法和普通方法关系
(1). 构造方法和普通方法的区别[1]. 普通方法必须有返回值类型,可以有参数
【结论】
因此Method类提供了get[Generic]ReturnType() 和get[Generic]ParameterTyps()两类方法分别对返回值类型和参数列表类型进行获取。
[2]. 构造方法必须没有返回值类型,可以有参数
【结论】
因此Constructor类仅仅提供了get[Generic]ParameterTyps()一类方法对构造方法的参数列表类型进行获取。
2). Constructor与泛型相关的方法
(1). 获取构造方法的普通参数类型数组[1]. 源码声明:
public Class<?>[] getParameterTypes();
[2]. 返回值类型:Class元素类型的数组 Class<?>[]
(2). 获取构造方法的泛型参数类型数组
[1]. 源码声明:
public Type[] getGenericParameterTypes();
[2]. 返回值类型:Type元素类型的数组 Type[]
(3). getParameterTypes()和getGenericParameterTypes() 举例
[1]. 待测试的构造方法及其所在的类
class ClassConstructor{ //泛型构造函数 public <E extends Thread> ClassConstructor(E e, int i, ArrayList<E> al, Collection<? extends E> coll, String str,Map<String, Date>[] maps){ //..... } }
[2]. 测试代码
Class clazz =ClassConstructor.class; Constructor cons=clazz.getConstructor(Thread.class, int.class, ArrayList.class, Collection.class, String.class, Map[].class); Type[] genericParameterTypes=cons.getGenericParameterTypes(); Class[] commonParameterTypes =cons.getParameterTypes(); System.out.println("genericParameterTypes.length==commonParameterTypes.length:"+(genericParameterTypes.length ==commonParameterTypes.length)); for(int i=0; i< genericParameterTypes.length; i++){ System.out.println("Generic Type: "+ genericParameterTypes[i] +"** Common Type: "+ commonParameterTypes[i]); }
[3]. 测试结果
【结论】由于构造方法可以看成特殊的方法,所以Constructor这两个方法的特点和同Method相应方法的特点一致(不再敖述,参见以前日志关于Method对这两个方法的对比)
(4). 通过Constructor反射解析泛型构造方法
[1]. 通过第一次关联获取Constructor对象
[2]. 通过Constructor对象的getGenericParameterTypes( )方法获取Type类型的数组
[3]. 对Type[]中每一个成员,根据参数已知得到Type接口子接口或者子类类型,强转为相应的子类接口或者子类类型的实例,根据五种类型(ParameterizedType,TypeVariable,
GenericArrayType,WildcardType和Class) 的具体处理方法获取每个参数的泛型细节类型。[具体不在说明,Method反射普通方法的日志里面给出了各种详细的说明]
[4]. 这一步是[3]的替代:递归解析到最后
由于泛型可以复合成复杂的嵌套复杂类型,但是各种子类型或者子接口的处理方法每一次仅仅是对其中一层<>或者[]进行处理,所以解析之后并不是最后的原始类型,因此有必要进行解析到底。【在使用递归对任意复合类型进行彻底解剖中对这种递归操作进行了详细的阐述,这里不再重复】。
2. 通过Field反射解析泛型成员变量
1). Field与泛型有关的方法
(1). 成员变量出现泛型的位置注意成员变量出现泛型的位置只能出现在变量的类型上,并且一个变量的类型就是唯一的。
因此Field类就提供了getGenericType()和getType()对泛型类型和普通类型的成员变量进行处理。
(2). 获取成员变量的普通类型
[1]. 源码声明:
public Class<?> getType();
[2]. 返回值类型:Class<?>
(3). 获取成员变量的泛型类型
[1]. 源码声明:
public Type getGenericType();
[2]. 返回值类型:Type
(4). getType() 和 getGenericType()的举例
[1]. 测试的成员变量及其所在的方法
class ClassField<E>{ private ArrayList<String> al1; private ArrayList<? extends Number> al2; private int i; private E e; private E[][] eArr; }
[2]. 对Field处理泛型字段的封装
public static void analyzeFieldType(String className,String propertyName) throws ClassNotFoundException, NoSuchFieldException{ Classclazz =Class.forName(className); //属性是私有的 所以使用getDeclaredField方法进行获取 Fieldfield =clazz.getDeclaredField(propertyName); TypegenericType =field.getGenericType(); Class<?>commonType =field.getType(); System.out.println("Generic Type: "+ genericType +"*******Common Type: "+ commonType); }
[3]. 测试private ArrayList<String>al1;
{1}. 测试代码:
String className ="ClassField"; String propertyName ="al1"; analyzeFieldType(className, propertyName);
{2}. 测试结果:
Generic Type:java.util.ArrayList<java.lang.String>*******Common Type: class java.util.ArrayList
[4]. 测试private ArrayList<?extends Number>
al2;
{1}. 测试代码:
String className ="ClassField"; String propertyName ="al2"; analyzeFieldType(className, propertyName);
{2}. 测试结果:
Generic Type: java.util.ArrayList<? extendsjava.lang.Number>*******Common Type: class java.util.ArrayList
[5]. 测试private
int i;
{1}. 测试代码:
String className ="ClassField"; String propertyName ="i"; analyzeFieldType(className, propertyName);
{2}. 测试结果:
Generic Type:int*******Common Type: int
[6]. 测试private E e;
{1}. 测试代码:
String className ="ClassField"; String propertyName ="e"; analyzeFieldType(className, propertyName);
{2}. 测试结果:
Generic Type: E*******CommonType: class java.lang.Object
[7]. 测试private E[][]eArr;
{1}. 测试代码:
String className ="ClassField"; String propertyName ="eArr"; analyzeFieldType(className, propertyName);
{2}. 测试结果:
Generic Type:E[][]*******Common Type: class[[Ljava.lang.Object;
【总结】这两种方法的规律和Constructor、Method对应的方法规律是一样的。
如果想进行反射操作,步骤也是和这这两个类一致的。如果想进一步细化子类型,那就使用递归。这些在前面Method反射操作泛型方法都有详细的介绍,不再重复。
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
相关文章推荐
- 黑马程序员--Java基础加强--15.利用反射操作泛型IV【通过反射Method解析泛型方法思路】【通过Method对四种Type子接口类型进行解剖】【使用递归对任意复合泛型类型进行彻底解剖】【个人
- 黑马程序员--Java基础加强--14.利用反射操作泛型III【解析关于泛型类型的细节信息的获取方法】【Method与泛型相关的方法】【个人总结】
- 黑马程序员--Java基础加强--17.利用反射操作泛型VI【泛型类型变量的语义】【GenericDeclaration接口】【泛型接口TypeVariable】【通过Class反射解析泛型类】
- 黑马程序员--Java基础加强--13.利用反射操作泛型II【TypeVariable】【GenericArrayType】【WildcardType】【Type及其子接口的来历】【个人总结】
- 黑马程序员--Java基础加强--12.利用反射操作泛型I【与反射+泛型相关的接口类型综述】【Type】【ParameterizedType】【个人总结】
- 黑马程序员--Java基础加强--07.【反射创建对象 操作字段 调用方法的异同】【个人总结】
- Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用
- Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用
- 黑马程序员--Java基础加强--10.【PropertyDescriptor操作JavaBean VS 反射操作Java类】【个人总结】
- 黑马程序员--Java基础加强--02.代码简化 书写规律I_原始数据类型【重载】【多态】【泛型】【泛型限定】【个人总结】
- 黑马程序员--Java基础加强--06.【泛型通配符限定】【个人总结】
- 黑马程序员--Java基础加强--03.代码简化 书写规律II_参数化数据类型【重载】【多态】【泛型】【泛型限定】【个人总结】
- 黑马程序员--Java基础加强--11.【MyEclipse使用快捷键提取方法的要点】【个人总结】
- 黑马程序员Java基础加强成员方法的反射
- 黑马程序员--Java基础加强--05.【泛型通配符】【个人总结】
- 黑马程序员--Java基础加强--09.【MyEclipse的class文件所在的目录配置】【相对路径解析】【个人总结】
- 黑马程序员--Java基础加强--04.代码简化 书写规律III_数组参数【重载】【数组】【可变参数数组】【泛型可变参数数组】【个人总结】
- 黑马程序员---java基础加强_成员变量的反射
- java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。
- 黑马程序员_Java基础_面向对象(概述、类与对象关系、成员变量、封装private、构造函数和构造代码块、this关键字)