黑马程序员--Java基础加强--16.利用反射操作泛型V【通过Constructor反射解析泛型构造方法】【通过Field反射解析泛型成员变量】【个人总结】
来源:互联网 发布:风云2麒麟臂升阶数据 编辑:程序博客网 时间:2024/06/07 23:30
利用反射操作泛型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基础加强--16.利用反射操作泛型V【通过Constructor反射解析泛型构造方法】【通过Field反射解析泛型成员变量】【个人总结】
- 黑马程序员--Java基础加强--17.利用反射操作泛型VI【泛型类型变量的语义】【GenericDeclaration接口】【泛型接口TypeVariable】【通过Class反射解析泛型类】
- 黑马程序员--Java基础加强--15.利用反射操作泛型IV【通过反射Method解析泛型方法思路】【通过Method对四种Type子接口类型进行解剖】【使用递归对任意复合泛型类型进行彻底解剖】【个人
- 黑马程序员--Java基础加强--14.利用反射操作泛型III【解析关于泛型类型的细节信息的获取方法】【Method与泛型相关的方法】【个人总结】
- 黑马程序员--Java基础加强--12.利用反射操作泛型I【与反射+泛型相关的接口类型综述】【Type】【ParameterizedType】【个人总结】
- 黑马程序员--Java基础加强--13.利用反射操作泛型II【TypeVariable】【GenericArrayType】【WildcardType】【Type及其子接口的来历】【个人总结】
- 黑马程序员---java基础加强_成员变量的反射
- 通过反射操作泛型
- 黑马程序员Java基础加强成员方法的反射
- 黑马程序员--Java基础加强--10.【PropertyDescriptor操作JavaBean VS 反射操作Java类】【个人总结】
- 黑马程序员-通过反射获取泛型参数类型
- 黑马程序员-----通过反射获取泛型类型
- 黑马程序员--Java基础加强--07.【反射创建对象 操作字段 调用方法的异同】【个人总结】
- 反射-通过反射越过泛型检查
- Java 反射:Class类,动态加载类获取方法和成员变量构造信息,方法反射的基本操作,集合泛型的本质
- 黑马程序员——【Java反射学习】方法的反射/成员变量的反射/构造函数的反射
- 通过反射获取构造方法,成员变量及成员方法
- Java利用反射操作成员变量,方法
- vs2005 搭建cocos2dx环境初体验
- 论网络管理员对网站安全的措施(php+mysql站)
- 雅虎改LOGO还管用吗?
- 系统集成项目管理之项目变更管理
- 二分查找及其应用
- 黑马程序员--Java基础加强--16.利用反射操作泛型V【通过Constructor反射解析泛型构造方法】【通过Field反射解析泛型成员变量】【个人总结】
- poj 3683 Priest John's Busiest Day 2-SAT
- HDOJ 4621: Life Game
- windows环境下登陆远程lunxu主机
- 《智能简史》摘录---核弹的来龙去脉
- 微信让运营商们担忧 微信操作系统将让BA3们颤抖
- 做一个记事闹铃的软件笔记
- HDU1754:I Hate It
- 学习C语言技巧