美文网首页kankan(good)
反射工具类:获取到泛型对象的泛型类型

反射工具类:获取到泛型对象的泛型类型

作者: 小胖学编程 | 来源:发表于2023-01-17 13:11 被阅读0次

    工具类:

    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.lang.reflect.TypeVariable;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 泛型工具类,用于获取类对象绑定的泛型参数
     * @author skyfalling
     * @version 1.0.0
     */
    public class Generics {
    
      /**
       * 查找类对象clazz绑定的genericClass声明的泛型参数
       *
       * @param clazz        绑定泛型参数的类
       * @param genericClass 声明泛型的类
       * @param index        泛型在声明类中的索引位置
       * @return 如果绑定了泛型参数, 则返回泛型类型, 否则返回null
       */
      public static Class find(Class clazz, Class genericClass, int index) {
        if (!genericClass.isAssignableFrom(clazz)) {
          return null;
        }
        List<Type> types = getGenericTypes(clazz);
        for (Type type : types) {
          Class genericType = find(type, genericClass, index);
          if (genericType != null) {
            return genericType;
          }
        }
        return null;
      }
    
      /**
       * 查找类type上绑定的genericClass声明的泛型类型
       *
       * @param type         泛型对象
       * @param genericClass 声明泛型的类
       * @param index        泛型在声明类中的索引位置
       * @return
       */
      private static Class find(Type type, Class genericClass, int index) {
        if (type instanceof Class) {
          return find((Class) type, genericClass, index);
        }
        if (type instanceof ParameterizedType) {
          ParameterizedType pType = (ParameterizedType) type;
          Type rawType = pType.getRawType();
          if (rawType instanceof Class) {
            Class rawClass = (Class) rawType;
            if (rawClass == genericClass) {
              Type realType = pType.getActualTypeArguments()[index];
              if (realType instanceof Class) {
                return (Class) realType;
              } else if (realType instanceof ParameterizedType) {
                //这里是泛型的泛型
                return (Class) ((ParameterizedType) realType).getRawType();
              }
            } else if (genericClass.isAssignableFrom(rawClass)) {
              Map<String, Type> map = combine(pType.getActualTypeArguments(), rawClass);
              return find(rawClass, genericClass, index, map);
            }
          }
        }
        return null;
      }
    
      /**
       * 查找类currentClass上绑定的genericClass声明的泛型类型
       *
       * @param currentClass 绑定泛型参数的类
       * @param genericClass 声明泛型的类
       * @param index        泛型在声明类中的索引位置
       * @param typeMap      已绑定的泛型类型映射表
       * @return
       */
      private static Class find(Class currentClass, Class genericClass, int index, Map<String, Type> typeMap) {
        List<Type> types = getGenericTypes(currentClass);
        for (Type type : types) {
          if (type instanceof ParameterizedType) {
            ParameterizedType pType = (ParameterizedType) type;
            Type rawType = pType.getRawType();
            if (rawType instanceof Class) {
              Class rawClass = (Class) rawType;
              Map<String, Type> map = transfer(pType, typeMap);
              Type[] typeArray = map.values().toArray(new Type[0]);
              if (rawClass == genericClass) {
                Type realType = typeArray[index];
                if (realType instanceof Class) {
                  return (Class) realType;
                } else if (realType instanceof ParameterizedType) {
                  //这里是泛型的泛型
                  return (Class) ((ParameterizedType) realType).getRawType();
                }
              } else if (genericClass.isAssignableFrom(rawClass)) {
                return find(rawClass, genericClass, index, combine(typeArray, rawClass));
              }
            }
          }
        }
        return null;
      }
    
    
      /**
       * 获取当前类继承的父类和实现接口的泛型列表
       *
       * @param clazz
       * @return
       */
      private static List<Type> getGenericTypes(Class clazz) {
        if (clazz == Object.class) {
          return Collections.EMPTY_LIST;
        }
        List<Type> list = new ArrayList<>();
        Type[] types = clazz.getGenericInterfaces();
        for (Type type : types) {
          list.add(type);
        }
        list.add(clazz.getGenericSuperclass());
        return list;
      }
    
      /**
       * 构建泛型映射表
       *
       * @param typeArguments 泛型参数
       * @param rawClass      声明泛型的类
       * @return
       */
      private static Map<String, Type> combine(Type[] typeArguments, Class rawClass) {
        Map<String, Type> map = new LinkedHashMap<>(typeArguments.length);
        TypeVariable[] typeParameters = rawClass.getTypeParameters();
        for (int i = 0; i < typeParameters.length; i++) {
          map.put(typeParameters[i].getName(), typeArguments[i]);
        }
        return map;
      }
    
    
      /**
       * 转换泛型映射表
       *
       * @param parameterizedType 绑定参数类型的泛型对象
       * @param typeMap           已绑定的泛型类型映射表
       * @return
       */
      private static Map<String, Type> transfer(ParameterizedType parameterizedType, Map<String, Type> typeMap) {
    
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        TypeVariable[] typeParameters = ((Class) parameterizedType.getRawType()).getTypeParameters();
        Map<String, Type> map = new LinkedHashMap<>();
        for (int i = 0; i < actualTypeArguments.length; i++) {
          Type type = actualTypeArguments[i];
          if (type instanceof TypeVariable) {
            String variableName = ((TypeVariable) type).getName();
            map.put(variableName, typeMap.get(variableName));
          } else {
            map.put(typeParameters[i].getName(), type);
          }
        }
        return map;
      }
    }
    

    使用方式:

    定义泛型接口:

    public interface Node<T, R> {
        R execute(T param);
    
        default Class<T> paramType() {
            return Generics.find(this.getClass(), Node.class, 0);
        }
    }
    

    定义泛型类:

    public class MyNode implements Node<String, User> {
        @Override
        public User execute(String param) {
    
            Class<String> stringClass = paramType();
    
            System.out.println(stringClass);
    
            return null;
        }
    
        public static void main(String[] args) {
            MyNode myNode=new MyNode();
            myNode.execute("123");
        }
    

    附录

    代码来源的git地址

    相关文章

      网友评论

        本文标题:反射工具类:获取到泛型对象的泛型类型

        本文链接:https://www.haomeiwen.com/subject/mfgthdtx.html