|
|
@@ -1,6 +1,7 @@
|
|
|
package cn.hutool.core.util;
|
|
|
|
|
|
-import cn.hutool.core.map.TableMap;
|
|
|
+import cn.hutool.core.lang.ParameterizedTypeImpl;
|
|
|
+import cn.hutool.core.lang.reflect.ActualTypeMapperPool;
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
import java.lang.reflect.Method;
|
|
|
@@ -8,6 +9,7 @@ import java.lang.reflect.ParameterizedType;
|
|
|
import java.lang.reflect.Type;
|
|
|
import java.lang.reflect.TypeVariable;
|
|
|
import java.lang.reflect.WildcardType;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
/**
|
|
|
* 针对 {@link Type} 的工具类封装<br>
|
|
|
@@ -282,117 +284,110 @@ public class TypeUtil {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取泛型变量和真实类型的对应表,使用{@link TableMap}表示,key不会重复<br>
|
|
|
- * 由于子类中泛型参数实现和父类(接口)中泛型定义位置是一一对应的,因此可以通过对应关系找到泛型实现类型<br>
|
|
|
- * 使用此方法注意:
|
|
|
- *
|
|
|
- * <pre>
|
|
|
- * 1. typeDefineClass必须是clazz的父类或者clazz实现的接口
|
|
|
- * </pre>
|
|
|
+ * 是否未知类型<br>
|
|
|
+ * type为null或者{@link TypeVariable} 都视为未知类型
|
|
|
*
|
|
|
- * @param actualType 真实类型所在类,此类中记录了泛型参数对应的实际类型
|
|
|
- * @param typeDefineClass 泛型变量声明所在类或接口,此类中定义了泛型类型
|
|
|
- * @return 给定泛型参数对应的实际类型,如果无对应类型,返回null
|
|
|
- * @since 5.4.1
|
|
|
+ * @param type Type类型
|
|
|
+ * @return 是否未知类型
|
|
|
+ * @since 4.5.2
|
|
|
*/
|
|
|
- public static TableMap<String, Type> getActualTypeMap(Type actualType, Class<?> typeDefineClass) {
|
|
|
- if (false == typeDefineClass.isAssignableFrom(getClass(actualType))) {
|
|
|
- throw new IllegalArgumentException("Parameter [superClass] must be assignable from [clazz]");
|
|
|
- }
|
|
|
-
|
|
|
- // 泛型参数标识符列表
|
|
|
- final TypeVariable<?>[] typeVars = typeDefineClass.getTypeParameters();
|
|
|
- if (ArrayUtil.isEmpty(typeVars)) {
|
|
|
- return new TableMap<>(0);
|
|
|
- }
|
|
|
-
|
|
|
- // 实际类型列表
|
|
|
- final Type[] actualTypeArguments = TypeUtil.getTypeArguments(actualType);
|
|
|
- if (ArrayUtil.isEmpty(actualTypeArguments)) {
|
|
|
- return new TableMap<>(0);
|
|
|
- }
|
|
|
-
|
|
|
- return new TableMap<>(ArrayUtil.map(typeVars, String.class, TypeVariable::getName), actualTypeArguments);
|
|
|
+ public static boolean isUnknown(Type type) {
|
|
|
+ return null == type || type instanceof TypeVariable;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取指定泛型变量对应的真实类型<br>
|
|
|
- * 由于子类中泛型参数实现和父类(接口)中泛型定义位置是一一对应的,因此可以通过对应关系找到泛型实现类型<br>
|
|
|
- * 使用此方法注意:
|
|
|
- *
|
|
|
- * <pre>
|
|
|
- * 1. superClass必须是clazz的父类或者clazz实现的接口
|
|
|
- * 2. typeVariable必须在superClass中声明
|
|
|
- * </pre>
|
|
|
+ * 指定泛型数组中是否含有泛型变量
|
|
|
*
|
|
|
- * @param actualType 真实类型所在类,此类中记录了泛型参数对应的实际类型
|
|
|
- * @param typeDefineClass 泛型变量声明所在类或接口,此类中定义了泛型类型
|
|
|
- * @param typeVariables 泛型变量,需要的实际类型对应的泛型参数
|
|
|
- * @return 给定泛型参数对应的实际类型,如果无对应类型,返回null
|
|
|
+ * @param types 泛型数组
|
|
|
+ * @return 是否含有泛型变量
|
|
|
* @since 4.5.7
|
|
|
*/
|
|
|
- public static Type[] getActualTypes(Type actualType, Class<?> typeDefineClass, Type... typeVariables) {
|
|
|
- final TableMap<String, Type> tableMap = getActualTypeMap(actualType, typeDefineClass);
|
|
|
-
|
|
|
- // 查找方法定义所在类或接口中此泛型参数的位置
|
|
|
- final Type[] result = new Type[typeVariables.length];
|
|
|
- for (int i = 0; i < typeVariables.length; i++) {
|
|
|
- result[i] = (typeVariables[i] instanceof TypeVariable)
|
|
|
- ? tableMap.get(((TypeVariable<?>) typeVariables[i]).getName())
|
|
|
- : typeVariables[i];
|
|
|
+ public static boolean hasTypeVeriable(Type... types) {
|
|
|
+ for (Type type : types) {
|
|
|
+ if (type instanceof TypeVariable) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
- return result;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取指定泛型变量对应的真实类型<br>
|
|
|
- * 由于子类中泛型参数实现和父类(接口)中泛型定义位置是一一对应的,因此可以通过对应关系找到泛型实现类型<br>
|
|
|
- * 使用此方法注意:
|
|
|
+ * 获取泛型变量和泛型实际类型的对应关系Map
|
|
|
*
|
|
|
- * <pre>
|
|
|
- * 1. superClass必须是clazz的父类或者clazz实现的接口
|
|
|
- * 2. typeVariable必须在superClass中声明
|
|
|
- * </pre>
|
|
|
+ * @param clazz 被解析的包含泛型参数的类
|
|
|
+ * @return 泛型对应关系Map
|
|
|
+ */
|
|
|
+ public static Map<Type, Type> getTypeMap(Class<?> clazz) {
|
|
|
+ return ActualTypeMapperPool.get(clazz);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获得泛型字段对应的泛型实际类型,如果此变量没有对应的实际类型,返回null
|
|
|
*
|
|
|
- * @param actualType 真实类型所在类,此类中记录了泛型参数对应的实际类型
|
|
|
- * @param typeDefineClass 泛型变量声明所在类或接口,此类中定义了泛型类型
|
|
|
- * @param typeVariable 泛型变量,需要的实际类型对应的泛型参数
|
|
|
- * @return 给定泛型参数对应的实际类型
|
|
|
- * @since 4.5.2
|
|
|
+ * @param type 实际类型明确的类
|
|
|
+ * @param field 字段
|
|
|
+ * @return 实际类型,可能为Class等
|
|
|
*/
|
|
|
- public static Type getActualType(Type actualType, Class<?> typeDefineClass, Type typeVariable) {
|
|
|
- final Type[] types = getActualTypes(actualType, typeDefineClass, typeVariable);
|
|
|
- if (ArrayUtil.isNotEmpty(types)) {
|
|
|
- return types[0];
|
|
|
+ public static Type getActualType(Type type, Field field) {
|
|
|
+ if(null == field){
|
|
|
+ return null;
|
|
|
}
|
|
|
- return null;
|
|
|
+ return getActualType(ObjectUtil.defaultIfNull(type, field.getDeclaringClass()), field.getGenericType());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 是否未知类型<br>
|
|
|
- * type为null或者{@link TypeVariable} 都视为未知类型
|
|
|
+ * 获得泛型变量对应的泛型实际类型,如果此变量没有对应的实际类型,返回null
|
|
|
+ * 此方法可以处理
|
|
|
*
|
|
|
- * @param type Type类型
|
|
|
- * @return 是否未知类型
|
|
|
- * @since 4.5.2
|
|
|
+ * @param type 类
|
|
|
+ * @param typeVariable 泛型变量,例如T等
|
|
|
+ * @return 实际类型,可能为Class等
|
|
|
*/
|
|
|
- public static boolean isUnknow(Type type) {
|
|
|
- return null == type || type instanceof TypeVariable;
|
|
|
+ public static Type getActualType(Type type, Type typeVariable) {
|
|
|
+ if (typeVariable instanceof ParameterizedType) {
|
|
|
+ return getActualType(type, (ParameterizedType)typeVariable);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (typeVariable instanceof TypeVariable) {
|
|
|
+ return ActualTypeMapperPool.getActualType(type, (TypeVariable<?>) typeVariable);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 没有需要替换的泛型变量,原样输出
|
|
|
+ return typeVariable;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 指定泛型数组中是否含有泛型变量
|
|
|
+ * 获得泛型变量对应的泛型实际类型,如果此变量没有对应的实际类型,返回null
|
|
|
+ * 此方法可以处理
|
|
|
*
|
|
|
- * @param types 泛型数组
|
|
|
- * @return 是否含有泛型变量
|
|
|
- * @since 4.5.7
|
|
|
+ * @param type 类
|
|
|
+ * @param parameterizedType 泛型变量,例如List<T>等
|
|
|
+ * @return 实际类型,可能为Class等
|
|
|
*/
|
|
|
- public static boolean hasTypeVeriable(Type... types) {
|
|
|
- for (Type type : types) {
|
|
|
- if (type instanceof TypeVariable) {
|
|
|
- return true;
|
|
|
+ public static Type getActualType(Type type, ParameterizedType parameterizedType) {
|
|
|
+ // 字段类型为泛型参数类型,解析对应泛型类型为真实类型,类似于List<T> a
|
|
|
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
|
|
+
|
|
|
+ // 泛型对象中含有未被转换的泛型变量
|
|
|
+ if (TypeUtil.hasTypeVeriable(actualTypeArguments)) {
|
|
|
+ actualTypeArguments = getActualTypes(type , parameterizedType.getActualTypeArguments());
|
|
|
+ if (ArrayUtil.isNotEmpty(actualTypeArguments)) {
|
|
|
+ // 替换泛型变量为实际类型,例如List<T>变为List<String>
|
|
|
+ parameterizedType = new ParameterizedTypeImpl(actualTypeArguments, parameterizedType.getOwnerType(), parameterizedType.getRawType());
|
|
|
}
|
|
|
}
|
|
|
- return false;
|
|
|
+
|
|
|
+ return parameterizedType;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获得泛型变量对应的泛型实际类型,如果此变量没有对应的实际类型,返回null
|
|
|
+ *
|
|
|
+ * @param type 类
|
|
|
+ * @param typeVariables 泛型变量数组,例如T等
|
|
|
+ * @return 实际类型数组,可能为Class等
|
|
|
+ */
|
|
|
+ public static Type[] getActualTypes(Type type, Type... typeVariables) {
|
|
|
+ return ActualTypeMapperPool.getActualTypes(type, typeVariables);
|
|
|
}
|
|
|
}
|