java.lang.reflect中的泛型结构体系
从jdk1.5开始,Java引入了泛型的特性,同时也在reflect包下提供了对反射泛型的支持。
废话不多说,通过一个uml类图,了解一下相关的类和接口,下面再详细说明。
Type
这个接口非常重要,jdk关于Type接口的介绍:
Type是Java语言中所有类型的共同父接口。这些类型包括原生类型,参数化类型,数组类型,类型变量以及基本数据类型。Class实现了这个接口。
raw types : Java类和接口
parameterized types : 参数化类型,如List<String>就是一个参数化类型
type variables : 类型参数,如java.util.List<E>中的E,即为类型变量
primitive types : 基本数据类型,包括 int、double、float、short、byte、long、char、boolean
GenericDeclaration
jdk解释的很清楚了,所有声明了类型变量的实体都应该实现这个接口。
实现了这个接口的有Class和Method,所以Java中有泛型类和泛型方法。
TypeVariable
在Type中,已经解释了TypeVariable的含义,他就是声明泛型声明中的参数变量,如java.util.List<E>中的E :
看一下TypeVariable类型的声明:
这里要注意到,TypeVariable自身也声明了泛型参数D,代表泛型参数所属的实体对象,GenericDeclaration代表的可能是一个Class或Method。
ParameterizedType
参数化类型,如我们在代码中声明了一个数据域:
List<String>就是一个参数化类型。
ParameterizedType中定义了获取泛型参数实际类型的方法:
WildcardType
通配符类型,如:
?extend Number 就是WildcardType,当然,它也是TypeVariable类型的
GenericArrayType
故名思义,它代表的是泛型数组类型,如:
GenericArrayType中定义了获取数组元素类型的方法:
示例代码
下面的类型仅仅为了展示反射泛型API的用法,没有任何业务上的含义:
package org.lin.rg;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
//泛型类
public class GenericType <L extends List<String>,
T extends SuperClass & Interface1 & Interface2>{ //仅仅是标记类型和接口,内不含方法
//泛型数组
@SuppressWarnings({ "unused", "unchecked" })
private Class<? extends Number>[] numberTypes = new Class[10];
@SuppressWarnings({ "unused" })
private List<String> list = new ArrayList<>();
@SuppressWarnings("unused")
private List<? extends Number> numberList = new ArrayList<>();
//带泛型类参数的方法
public List<String> getList(Map<String, Object> map, List<Integer> list) {
return null;
}
static class Foo extends SuperClass implements Interface1, Interface2 {}
@SuppressWarnings("rawtypes")
public static void showTypeVariables() {
Class<GenericType> clazz = GenericType.class;
//这个方法在GenericDeclaration中定义,用于获取类型变量
TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
System.out.println("打印" + clazz.getSimpleName() + "定义的参数类型:");
for (TypeVariable<?> param : typeParameters) {
System.out.println("参数名:" + param.getName());
System.out.println("参数上界列表:" + Arrays.asList(param.getBounds()));
}
System.out.println();
}
public static void showParameterType() {
//这里,我用list数据域展示ParameterizedType API
try {
Field field = GenericType.class.getDeclaredField("list");
//注意,一定要使用带Generic前缀的方法
Type fieldType = field.getGenericType();
System.out.println("ParameterizedType: " + fieldType);
if (fieldType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)fieldType;
Type actualType = pt.getActualTypeArguments()[0];
System.out.println(actualType);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println();
}
public static void showWildcardType() {
try {
Field field = GenericType.class.getDeclaredField("numberList");
ParameterizedType fieldType = (ParameterizedType)field.getGenericType();
WildcardType wt = (WildcardType)fieldType.getActualTypeArguments()[0];
System.out.println("WildcardType upperBounds:" + Arrays.asList(wt.getUpperBounds()));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println();
}
public static void showGenericArrayType() {
try {
Field field = GenericType.class.getDeclaredField("numberTypes");
GenericArrayType gat = (GenericArrayType)field.getGenericType();
System.out.println("array component type :" + gat.getGenericComponentType());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
showTypeVariables();
showParameterType();
showWildcardType();
showGenericArrayType();
}
}
输出: