简介
说明
Type 是java反射机制中提供的一个接口,用来表示java中的所有类型的接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。(这段话是Type源码的注释中写的)。
- 原始类型:一般意义上的java类,由class类实现
- 参数化类型:ParameterizedType接口的实现类
- 数组类型:GenericArrayType接口的实现类
- 类型变量:TypeVariable接口的实现类
- 基本类型:int,float等java基本类型。(其实也是class)
Type类几乎在各种框架中都能看到,尤其是涉及代理,反射的地方。理解好Type类也会对今后框架封装、源码解读有很大好处。
Type接口源码
package java.lang.reflect;
/**
* Type is the common superinterface for all types in the Java
* programming language. These include raw types, parameterized types,
* array types, type variables and primitive types.
*
* @since 1.5
*/
public interface Type {
/**
* Returns a string describing this type, including information
* about any type parameters.
*
* @implSpec The default implementation calls {@code toString}.
*
* @return a string describing this type
* @since 1.8
*/
default String getTypeName() {
return toString();
}
}
Type的子接口/子类
Type的子接口/子类是这样的:

实例
下边我只用字段进行示例。方法、类都是一样的用法。
Class
Class的方法实在太多了,毕竟它包含了类的所有信息。详细可见这里:Java反射-反射的应用 – 自学精灵
本处只做一个简单的示例。
package com.example.a;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
class ClassTest{
private String userName;
public void sayHello() {
System.out.println("Hello");
}
}
public class Demo {
public static void main(String[] args) {
Field[] declaredFields = ClassTest.class.getDeclaredFields();
Method[] declaredMethods = ClassTest.class.getDeclaredMethods();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName());
}
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName());
}
}
}
ParameterizedType
参数化类型,即带泛型的类型;例如:List<T>、Map<K,V>。
源码
public interface ParameterizedType extends Type {
//获取参数化类型参数。例如:Map<K,V>,则为K/V数组;
Type[] getActualTypeArguments();
//获取原始类型,泛型类型。例如:List<T> ,则为 List
Type getRawType();
//如果是内部类,获取拥有内部类的外部类。例如:Map.Entry<K,V>,则为Map
Type getOwnerType();
}
实例
package com.example.a;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
class ParameterizedTypeTest<T> {
private List<T> tList;
private Map<String, Integer> stringIntegerMap;
}
public class Demo {
public static void main(String[] args) {
Field[] declaredFields = ParameterizedTypeTest.class.getDeclaredFields();
for (Field declaredField : declaredFields) {
// 获得字段的类型
Type type = declaredField.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
// 参数类型名。输出:List<T> 和 Map<String,Integer>
System.out.println("typeName: " + parameterizedType.getTypeName());
// 父类。本处都是Null
System.out.println("ownerType: " + parameterizedType.getOwnerType());
// 原始类型。输出:interface java.util.List/Map
System.out.println("rawType: " + parameterizedType.getRawType());
// 参数实际类型。输出:T和java.lang.String/Integer
for (Type arguments : parameterizedType.getActualTypeArguments()) {
System.out.println(arguments.getTypeName());
}
}
System.out.println("----------------------------------");
}
}
}
运行结果
typeName: java.util.List<T> ownerType: null rawType: interface java.util.List T ---------------------------------- typeName: java.util.Map<java.lang.String, java.lang.Integer> ownerType: null rawType: interface java.util.Map java.lang.String java.lang.Integer ----------------------------------
TypeVariable
类型变量,即泛型中的变量;例如:T、K、V等变量,可以表示任何类;
TypeVariable代表着泛型中的变量,而ParameterizedType则代表整个泛型。
源码
public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
//获得该类型变量的上限,也就是泛型中extend右边的值;
// 例如: List<T extends Number> ,Number就是类型变量T的上限;
Type[] getBounds();
//获取声明该类型变量实体
D getGenericDeclaration();
String getName();
AnnotatedType[] getAnnotatedBounds();
}
实例
package com.example.a;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;
import java.util.Map;
class TypeVariableTest<T> {
private List<Integer> integerList;
private Map<String, T> stringTMap;
}
public class Demo {
public static void main(String[] args) {
Class<TypeVariableTest> clazz = TypeVariableTest.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
Type type = declaredField.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType)type;
for (Type type1 : parameterizedType.getActualTypeArguments()) {
if (type1 instanceof TypeVariable) {
TypeVariable typeVariable = (TypeVariable) type1;
System.out.println("字段名: " + declaredField.getName());
System.out.println("typeName: " + typeVariable.getTypeName());
System.out.println("genericDeclaration: " +
typeVariable.getGenericDeclaration());
}
}
}
}
}
}
执行结果
字段名: stringTMap typeName: T genericDeclaration: class com.example.a.TypeVariableTest
可以发现,经过代码的过滤后,只获取到了T。
GenericArrayType
简介
泛型数组类型,用来描述ParameterizedType、TypeVariable类型的数组;例如:List<T>[] 、T[]、List<Integer>[]等。不包含String[]、int[]这种。
源码
public interface GenericArrayType extends Type {
//可以获取到数组前面的类型。例如:List<String>[]为List<String>
Type getGenericComponentType();
}
实例
package com.example.a;
import java.lang.reflect.*;
import java.util.List;
class TypeVariableTest<T> {
private T[] ts;
private Integer[] integers;
private List<Integer>[] integerList;
private List<T>[] tLists;
}
public class Demo {
public static void main(String[] args) {
Class<TypeVariableTest> clazz = TypeVariableTest.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
Type type = declaredField.getGenericType();
if (type instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType)type;
System.out.println("字段名: " + declaredField.getName());
System.out.println("typeName: " +
genericArrayType.getTypeName());
System.out.println("genericComponentType: " +
genericArrayType.getGenericComponentType());
}
System.out.println("------------------------------------------");
}
}
}
执行结果
字段名: ts typeName: T[] genericComponentType: T ------------------------------------------ ------------------------------------------ 字段名: integerList typeName: java.util.List<java.lang.Integer>[] genericComponentType: java.util.List<java.lang.Integer> ------------------------------------------ 字段名: tLists typeName: java.util.List<T>[] genericComponentType: java.util.List<T> ------------------------------------------
可见:Integer[]这种不属于GenericArrayType
WildType
简介
泛型表达式(通配符表达式)。例如:? extend Number、? super Integer。
WildcardType虽然是Type的子接口,但却不是Java类型中的一种。
源码
public interface WildcardType extends Type {
// 获取上边界。例如:List<? extends Number>,则为Number
Type[] getUpperBounds();
// 获取下边界。例如:List<? super String>, 则为String
Type[] getLowerBounds();
}
实例
package com.example.a;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.List;
class TypeVariableTest {
private List<? extends Integer> integerList;
}
public class Demo {
public static void main(String[] args) {
Class<TypeVariableTest> clazz = TypeVariableTest.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
Type type = declaredField.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
System.out.println("字段名: " + declaredField.getName());
for (Type type1 : typeArguments) {
if (type1 instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type1;
System.out.println("typeName: " + wildcardType.getTypeName());
System.out.println("upperBounds: " +
Arrays.toString(wildcardType.getUpperBounds()));
}
}
}
}
}
}
执行结果
字段名: integerList typeName: ? extends java.lang.Integer upperBounds: [class java.lang.Integer]
框架对Type的应用
Mybatis
org.apache.ibatis.reflection.Reflector中的typeClass方法将Type类型对象转换为Class对象。
private Class<?> typeToClass(Type src) {
Class<?> result = null;
// 如果src是Class类型的实例则直接进行强制类型转换
if (src instanceof Class) {
result = (Class<?>) src;
// 如果src是参数类型则获取其原始类型Class对象;
} else if (src instanceof ParameterizedType) {
result = (Class<?>) ((ParameterizedType) src).getRawType();
// 如果src是数组泛型类型,则分情况处理
} else if (src instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) src).getGenericComponentType();
if (componentType instanceof Class) {
result = Array.newInstance((Class<?>) componentType, 0).getClass();
} else {
Class<?> componentClass = typeToClass(componentType);
result = Array.newInstance(componentClass, 0).getClass();
}
}
if (result == null) {
result = Object.class;
}
return result;
}

请先 !