类型工具-TypeUtil
# 1. 功能概述
TypeUtil 是 Hutool 提供的反射类型工具类,用于处理 Java 反射中的 Type 对象,提供了类型获取、类型转换、泛型参数解析等功能。该工具类简化了 Java 反射中类型操作的复杂性,特别是在处理泛型类型时提供了强大的支持。
# 2. 核心功能
# 2.1 类型获取与转换
- getClass(type):获得 Type 对应的原始类
- getType(field):获取字段对应的 Type 类型
- getFieldType(clazz, fieldName):获得字段的泛型类型
- isUnknown(type):判断是否为未知类型
- hasTypeVariable(types):检查泛型数组中是否含有泛型变量
# 2.2 方法参数类型
- getFirstParamType(method):获取方法的第一个参数类型
- getFirstParamClass(method):获取方法的第一个参数类
- getParamType(method, index):获取方法的指定索引参数类型
- getParamClass(method, index):获取方法的指定索引参数类
- getParamTypes(method):获取方法的参数类型列表
- getParamClasses(method):解析方法的参数类型类列表
# 2.3 方法返回值类型
- getReturnType(method):获取方法的返回值类型
- getReturnClass(method):解析方法的返回类型类
# 2.4 泛型参数类型
- getTypeArgument(type):获得给定类的第一个泛型参数
- getTypeArgument(type, index):获得给定类的指定索引泛型参数
- getTypeArguments(type):获得指定类型中所有泛型参数类型
- toParameterizedType(type):将 Type 转换为 ParameterizedType
- getGenerics(clazz):获取指定类所有泛型父类和泛型接口
# 2.5 实际类型获取
- getActualType(type, field):获得泛型字段对应的泛型实际类型
- getActualType(type, typeVariable):获得泛型变量对应的泛型实际类型
- getActualTypes(type, typeVariables):获得多个泛型变量对应的泛型实际类型
- getTypeMap(clazz):获取泛型变量和泛型实际类型的对应关系Map
- createParameterizedType(rawType, actualTypeArguments):创建泛型对象
# 3. 方法详解
# 3.1 类型获取与转换
# getClass(type)
功能:获得 Type 对应的原始类
参数:
type:Type 对象
返回值:原始类,如果无法获取原始类,返回 null
示例:
Type type = String.class;
Class<?> clazz = TypeUtil.getClass(type); // 返回 String.class
# getType(field)
功能:获取字段对应的 Type 类型
参数:
field:字段对象
返回值:Type 对象,可能为 null
说明:优先获取 GenericType,获取不到则获取 Type
示例:
Field field = User.class.getDeclaredField("name");
Type type = TypeUtil.getType(field);
# getFieldType(clazz, fieldName)
功能:获得字段的泛型类型
参数:
clazz:Bean 类fieldName:字段名
返回值:字段的泛型类型
示例:
Type type = TypeUtil.getFieldType(User.class, "name");
# isUnknown(type)
功能:判断是否为未知类型
参数:
type:Type 类型
返回值:是否为未知类型
说明:type 为 null 或者 TypeVariable 都视为未知类型
示例:
Type type = String.class;
boolean isUnknown = TypeUtil.isUnknown(type); // 返回 false
# hasTypeVariable(types)
功能:检查泛型数组中是否含有泛型变量
参数:
types:泛型数组
返回值:是否含有泛型变量
示例:
Type[] types = {String.class, Integer.class};
boolean hasTypeVar = TypeUtil.hasTypeVariable(types); // 返回 false
# 3.2 方法参数类型
# getFirstParamType(method)
功能:获取方法的第一个参数类型
参数:
method:方法对象
返回值:Type 对象,可能为 null
说明:优先获取方法的 GenericParameterTypes,如果获取不到,则获取 ParameterTypes
示例:
Method method = User.class.getMethod("setName", String.class);
Type type = TypeUtil.getFirstParamType(method); // 返回 String.class
# getFirstParamClass(method)
功能:获取方法的第一个参数类
参数:
method:方法对象
返回值:第一个参数类型,可能为 null
示例:
Method method = User.class.getMethod("setName", String.class);
Class<?> clazz = TypeUtil.getFirstParamClass(method); // 返回 String.class
# getParamType(method, index)
功能:获取方法的指定索引参数类型
参数:
method:方法对象index:第几个参数的索引,从 0 开始计数
返回值:Type 对象,可能为 null
示例:
Method method = User.class.getMethod("setUserInfo", String.class, int.class);
Type type = TypeUtil.getParamType(method, 1); // 返回 int.class
# getParamClass(method, index)
功能:获取方法的指定索引参数类
参数:
method:方法对象index:第几个参数的索引,从 0 开始计数
返回值:参数类,可能为 null
示例:
Method method = User.class.getMethod("setUserInfo", String.class, int.class);
Class<?> clazz = TypeUtil.getParamClass(method, 1); // 返回 int.class
# getParamTypes(method)
功能:获取方法的参数类型列表
参数:
method:方法对象
返回值:Type 列表,可能为 null
示例:
Method method = User.class.getMethod("setUserInfo", String.class, int.class);
Type[] types = TypeUtil.getParamTypes(method); // 返回 [String.class, int.class]
# getParamClasses(method)
功能:解析方法的参数类型类列表
参数:
method:方法对象
返回值:参数类型类列表
示例:
Method method = User.class.getMethod("setUserInfo", String.class, int.class);
Class<?>[] classes = TypeUtil.getParamClasses(method); // 返回 [String.class, int.class]
# 3.3 方法返回值类型
# getReturnType(method)
功能:获取方法的返回值类型
参数:
method:方法对象
返回值:Type 对象,可能为 null
示例:
Method method = User.class.getMethod("getName");
Type type = TypeUtil.getReturnType(method); // 返回 String.class
# getReturnClass(method)
功能:解析方法的返回类型类
参数:
method:方法对象
返回值:返回值类型的类
示例:
Method method = User.class.getMethod("getName");
Class<?> clazz = TypeUtil.getReturnClass(method); // 返回 String.class
# 3.4 泛型参数类型
# getTypeArgument(type)
功能:获得给定类的第一个泛型参数
参数:
type:被检查的类型,必须是已经确定泛型类型的类型
返回值:Type 对象,可能为 null
示例:
Type type = new TypeReference<List<String>>(){}.getType();
Type genericType = TypeUtil.getTypeArgument(type); // 返回 String.class
# getTypeArgument(type, index)
功能:获得给定类的指定索引泛型参数
参数:
type:被检查的类型,必须是已经确定泛型类型的类index:泛型类型的索引号,即第几个泛型类型
返回值:Type 对象
示例:
Type type = new TypeReference<Map<String, Integer>>(){}.getType();
Type keyType = TypeUtil.getTypeArgument(type, 0); // 返回 String.class
Type valueType = TypeUtil.getTypeArgument(type, 1); // 返回 Integer.class
# getTypeArguments(type)
功能:获得指定类型中所有泛型参数类型
参数:
type:指定类型
返回值:所有泛型参数类型
示例:
Type type = new TypeReference<Map<String, Integer>>(){}.getType();
Type[] genericTypes = TypeUtil.getTypeArguments(type); // 返回 [String.class, Integer.class]
# toParameterizedType(type)
功能:将 Type 转换为 ParameterizedType
参数:
type:Type 对象
返回值:ParameterizedType 对象
说明:ParameterizedType 用于获取当前类或父类中泛型参数化后的类型
示例:
Type type = new TypeReference<List<String>>(){}.getType();
ParameterizedType paramType = TypeUtil.toParameterizedType(type);
# getGenerics(clazz)
功能:获取指定类所有泛型父类和泛型接口
参数:
clazz:类
返回值:泛型父类或接口数组
示例:
class A<T> {}
class B extends A<String> implements List<Integer> {}
ParameterizedType[] generics = TypeUtil.getGenerics(B.class);
# 3.5 实际类型获取
# getActualType(type, field)
功能:获得泛型字段对应的泛型实际类型
参数:
type:实际类型明确的类field:字段对象
返回值:实际类型,可能为 Class 等
示例:
class A<T> {
private List<T> list;
}
class B extends A<String> {}
Field field = A.class.getDeclaredField("list");
Type actualType = TypeUtil.getActualType(B.class, field); // 返回 List<String>
# getActualType(type, typeVariable)
功能:获得泛型变量对应的泛型实际类型
参数:
type:泛型类typeVariable:泛型变量,例如 T 等
返回值:实际类型,可能为 Class 等
示例:
class A<T> {
private T value;
}
class B extends A<String> {}
TypeVariable<?>[] typeVars = A.class.getTypeParameters();
Type actualType = TypeUtil.getActualType(B.class, typeVars[0]); // 返回 String.class
# createParameterizedType(rawType, actualTypeArguments)
功能:创建泛型对象
参数:
rawType:原始类型,例如:List.classactualTypeArguments:实际类型,例如:String.class
返回值:泛型对象
示例:
Type listType = TypeUtil.createParameterizedType(List.class, String.class); // 创建 List<String> 类型
# getTypeMap(clazz)
功能:获取泛型变量和泛型实际类型的对应关系Map
参数:
clazz:被解析的包含泛型参数的类
返回值:泛型对应关系Map
示例:
class A<T, E> {}
class B extends A<String, Integer> {}
Map<Type, Type> typeMap = TypeUtil.getTypeMap(B.class);
// 返回:{T=String, E=Integer}
# 4. 示例代码
# 4.1 泛型参数获取
// 定义泛型类
class GenericClass<T, E> {
private T value;
private List<E> list;
}
// 继承泛型类并指定具体类型
class SpecificClass extends GenericClass<String, Integer> {
}
// 获取泛型参数类型
Field valueField = GenericClass.class.getDeclaredField("value");
Field listField = GenericClass.class.getDeclaredField("list");
// 获取实际类型
Type valueActualType = TypeUtil.getActualType(SpecificClass.class, valueField);
Type listActualType = TypeUtil.getActualType(SpecificClass.class, listField);
Console.log("value字段实际类型:{}", valueActualType); // 输出:value字段实际类型:class java.lang.String
Console.log("list字段实际类型:{}", listActualType); // 输出:list字段实际类型:java.util.List<java.lang.Integer>
# 4.2 方法类型获取
// 获取方法
Method method = User.class.getMethod("setUserInfo", String.class, int.class);
// 获取参数类型
Type[] paramTypes = TypeUtil.getParamTypes(method);
Class<?>[] paramClasses = TypeUtil.getParamClasses(method);
Console.log("参数类型:{}", Arrays.toString(paramTypes)); // 输出:参数类型:[class java.lang.String, int]
Console.log("参数类:{}", Arrays.toString(paramClasses)); // 输出:参数类:[class java.lang.String, int]
// 获取返回值类型
Type returnType = TypeUtil.getReturnType(method);
Class<?> returnClass = TypeUtil.getReturnClass(method);
Console.log("返回值类型:{}", returnType); // 输出:返回值类型:void
Console.log("返回值类:{}", returnClass); // 输出:返回值类:void
# 4.3 复杂泛型处理
// 定义复杂泛型类
class ComplexGeneric<T> {
private Map<String, List<T>> dataMap;
}
// 继承并指定具体类型
class ComplexImpl extends ComplexGeneric<Long> {
}
// 获取字段
Field dataMapField = ComplexGeneric.class.getDeclaredField("dataMap");
// 获取实际类型
Type actualType = TypeUtil.getActualType(ComplexImpl.class, dataMapField);
Console.log("复杂泛型实际类型:{}", actualType); // 输出:复杂泛型实际类型:java.util.Map<java.lang.String, java.util.List<java.lang.Long>>
// 获取泛型参数
Type[] typeArguments = TypeUtil.getTypeArguments(actualType);
for (int i = 0; i < typeArguments.length; i++) {
Console.log("泛型参数{}:{}", i, typeArguments[i]);
}
// 输出:
// 泛型参数0:class java.lang.String
// 泛型参数1:java.util.List<java.lang.Long>
# 4.4 类型映射获取
// 定义多层泛型
class GrandParent<A, B> {}
class Parent<T> extends GrandParent<T, Integer> {}
class Child extends Parent<String> {}
// 获取类型映射
Map<Type, Type> typeMap = TypeUtil.getTypeMap(Child.class);
Console.log("类型映射:{}", typeMap);
// 输出:类型映射:{A=class java.lang.String, B=class java.lang.Integer, T=class java.lang.String}
# 5. 注意事项
- 泛型类型确定:在使用泛型相关方法时,必须确保类型是已经确定的泛型类型,否则可能无法获取正确的泛型参数。
- Type类型支持:工具类支持多种Type类型,包括Class、ParameterizedType、TypeVariable、WildcardType、GenericArrayType等。
- null安全:大多数方法都进行了null检查,避免了空指针异常。
- 递归处理:对于复杂的泛型类型,工具类会递归处理,直到获取到最终的实际类型。
- 类型转换:在转换Type到Class时,会根据不同的Type类型进行不同的处理,确保返回正确的原始类。
- 泛型数组:支持泛型数组类型的处理,例如
List<String>[]。 - 接口泛型:getGenerics(clazz)方法会同时获取泛型父类和泛型接口。
# 6. 最佳实践
- 泛型类型获取:当需要获取泛型类型的实际参数时,优先使用TypeReference结合TypeUtil的方法。
- 方法参数检查:在动态调用方法前,可以使用TypeUtil获取方法的参数类型,进行参数类型检查。
- 泛型字段处理:对于泛型类中的字段,可以使用getActualType方法获取其实际类型。
- 复杂泛型解析:对于复杂的泛型结构,如
Map<List<String>,Set<Integer>>,可以使用getActualType方法递归解析。 - 类型映射缓存:TypeUtil内部使用了缓存机制,提高了频繁调用的性能。
- 创建泛型对象:使用createParameterizedType方法可以方便地创建泛型类型对象,用于反射操作。
TypeUtil 工具类为 Java 反射中的类型操作提供了全面的支持,特别是在处理泛型类型时表现出色。它简化了类型获取、转换和解析的复杂性,是 Hutool 反射模块中的核心工具类之一。