利用反射操作泛型I----
与反射+泛型相关的接口类型综述 Type接口ParameterizedType接口
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1. 和反射+泛型相关的接口类型概述
相关接口综述
(1). 和反射+泛型有关的接口类型
[1]. java.lang.reflect.Type:java语言中所有类型的公共父接口
[2]. java.lang.reflect.ParameterizedType
[3]. java.lang.reflect.GenericArrayType
[4]. java.lang.reflect.WildcardType
(2). 体系结构图
{1}. Type直接子接口
ParameterizedType,GenericArrayType,TypeVariable和WildcardType四种类型的接口
{1}1. ParameterizedType: 表示一种参数化的类型,比如Collection<String>
{1}2. GenericArrayType: 表示一种元素类型是参数化类型或者类型变量的数组类型
{1}3. TypeVariable: 是各种类型变量的公共父接口
{1}4. WildcardType: 代表一种通配符类型表达式
比如?, ? extends Number, ? super Integer【wildcard是一个单词:就是“通配符”】
{2}. Type直接实现子类 :Class类
2. java.lang.reflect.Type接口
Type类型接口基础知识
(1). Type接口的位置
位于java.lang.reflect反射子包中。
(2). Type接口类型的含义
[1]. API中的解释:Java编程语言中所有类型的公共父接口
[2].Type指代的类型
Type所有类型指代的有:原始类型 (raw types)【对应Class】,参数化类型 (parameterizedtypes)【对应ParameterizedType】, 数组类型 (array types)【对应GenericArrayType】,类型变量 (type variables)【对应TypeVariable】,基本数据类型(primitivetypes)【仍然对应Class】
(3). Type接口类型的源码
package java.lang.reflect;
public interface Type {}
【注意】Type接口中没有任何方法。
3. java.lang.reflect.ParameterizedType接口
ParameterizedType类型接口基础知识
(1). ParameterizedType接口基础知识
[1]. ParameterizedType接口的位置
ParameterizedType位于java.lang.reflect反射子包中。
[2]. ParameterizedType接口类型的含义
表示参数化类型。比如:Map<String, Date>这种参数化类型
[3]. ParameterizedType接口的源码
package java.lang.reflect;
import java.lang.reflect.MalformedParameterizedTypeException;
import java.lang.reflect.Type;
public interface ParameterizedType extends Type {
Type[] getActualTypeArguments();
Type getRawType();
Type getOwnerType();
}
(2). ParameterizedType接口的常用方法
[1]. 获取参数化类型<>中的实际类型
{1}. 源码声明:Type[] getActualTypeArguments();
【注意】无论<>中有几层<>嵌套,这个方法仅仅脱去最外层的<>之后剩下的内容就作为这个方法的返回值。
{2}. 返回值类型:Type元素数组 Type[ ]
【分析1】为什么返回的类型是数组类型呢?
因为一个方法的某个类型化参数<>中未必只有一个类型参数或者是具体化类型。可以用“,”进行多个类型参数或者具体化类型的分隔。
e.g. 最典型Map<String, Date> 这样getActualTypeArguments()必定返回一个以上的实际参数。所以,返回值类型一定是数组类型。
【分析2】为什么返回的数组类型的元素类型是Type这个父类类型呢?
假设一个方法是这样的:
public static <E> E methodIV(
ArrayList<ArrayList<Integer>> al1,
ArrayList<E> al2,
ArrayList<String> al3,
ArrayList<? extends Number> al4,
ArrayList<E[]> al5){}
那么他的每一参数总体上看都是参数化类型的。
{1}. 对于ArrayList<ArrayList<Integer>>,通过getActualTypeArguments()返回之后,脱去最外层的<>之后,剩余的类型是ArrayList<Integer>。因此对这个参数的返回类型是ParameterizedType。
{2}. 对于ArrayList<E>,通过getActualTypeArguments()返回之后,脱去最外层的<>之后,剩余的类型是E。因此对这个参数的返回类型是TypeVariable。
{3}. 对于ArrayList<String>,通过getActualTypeArguments()返回之后,脱去最外层的<>之后,剩余的类型是String。因此对这个参数的返回类型是Class。
{4}. 对于ArrayList<? extends Number>,通过getActualTypeArguments()返回之后,脱去最外层的<>之后,剩余的类型是? ExtendsNumber。因此对这个参数的返回类型是WildcardType。
{5}. 对于ArrayList<E[]>,通过getActualTypeArguments()返回之后,脱去最外层的<>之后,剩余的类型是E[]。因此对这个参数的返回类型是GenericArrayType。
所以,可能获得各种各样类型的实际参数,所以为了统一,采用直接父类数组Type[]进行接收。
[2]. 获取参数化类型<>前面的实际类型,也就是参数化类型对应的原始类型
{1}. 源码声明:Type getRawType();
{2}. 返回值类型:Type类型
[3] 为什么同一个ParameterizedType实现类的实例的getActualTypeArguments( )返回的类型是Type[ ],而getRawType()返回的类型是Type?
因为在一个原始类型后面的<>可以跟多个实际类型或者类型参数或者通配符表达式或者嵌套的参数化类型或者他们的组合。因此一个参数化类型的原始类型必定是1个,但是<>中的实际类型可以是多个。
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------