All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.t.util.common.GenericUtil Maven / Gradle / Ivy

package cn.t.util.common;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.List;

public class GenericUtil {

    /**
     * 获取类对象泛型结构
     * @param clazz xxx
     * @return xxx
     */
    public static ClassGeneric getGeneric(Class clazz) {
        if (clazz == null) {
            return null;
        }
        Type type = clazz.getGenericSuperclass();
        return doGetGeneric(type);
    }

    public static ClassGeneric doGetGeneric(Type type) {
        if (type == null) {
            return null;
        }
        //result
        ClassGeneric classGeneric = new ClassGeneric();
        //泛型颗粒
        List genericList = new ArrayList<>();
        //建立关系
        classGeneric.setGenericList(genericList);
        // 嵌套泛型
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            //泛型实际类型
            Type rawType = parameterizedType.getRawType();
            if (rawType instanceof Class) {
                Class superClass = (Class) rawType;
                if (!Object.class.equals(superClass)) {
                    TypeVariable[] superTypeVariables = superClass.getTypeParameters();
                    ClassGeneric superClassGeneric = new ClassGeneric();
                    List superGenericList = new ArrayList<>();
                    superClassGeneric.setGenericList(superGenericList);
                    for (TypeVariable superTypeVariable : superTypeVariables) {
                        Generic superGeneric = new Generic();
                        superGeneric.setType(superTypeVariable.getName());
                        superGenericList.add(superGeneric);
                    }
                    classGeneric.setParent(superClassGeneric);
                    Type superSuperClass = superClass.getSuperclass();
                    if (!Object.class.equals(superSuperClass)) {
                        Type superSuperType = superClass.getGenericSuperclass();
                        superClassGeneric.setParent(doGetGeneric(superSuperType));
                    }
                }
            }
            //加载父类泛型
            Type[] types = parameterizedType.getActualTypeArguments();
            for (Type t : types) {
                Generic generic = new Generic();
                if (t instanceof ParameterizedType) {
                    generic.setType(((ParameterizedType) t).getRawType().getTypeName());
                    generic.setEmbedClassGeneric(doGetGeneric(t));
                } else if (t instanceof TypeVariable) {
                    generic.setType(((TypeVariable) t).getName());
                } else if (t instanceof Class) {
                    generic.setType(((Class) t).getName());
                } else {
                    System.out.println("[warn] run in else");
                }
                genericList.add(generic);
            }

            // 处理泛型擦拭对象
        } else if (type instanceof TypeVariable) {
            Generic generic = new Generic();
            generic.setType(((TypeVariable) type).getName());
            genericList.add(generic);
            // class本身也是type,强制转型
        } else if (type instanceof Class) {// class本身也是type,强制转型
            Generic generic = new Generic();
            generic.setType(((Class) type).getName());
            genericList.add(generic);
        } else {
            System.out.println("[warn] run in else");
        }
        return classGeneric;
    }

    private static Class getClass(Type type, int i) {
        if (type instanceof ParameterizedType) { // 处理泛型类型
            return getGenericClass((ParameterizedType) type, i);
        } else if (type instanceof TypeVariable) {
            return getClass(((TypeVariable) type).getBounds()[0], 0); // 处理泛型擦拭对象
        } else {// class本身也是type,强制转型
            return (Class) type;
        }
    }

    private static Class getGenericClass(ParameterizedType parameterizedType, int i) {
        Object genericClass = parameterizedType.getActualTypeArguments()[i];
        if (genericClass instanceof ParameterizedType) { // 处理多级泛型
            return (Class) ((ParameterizedType) genericClass).getRawType();
        } else if (genericClass instanceof GenericArrayType) { // 处理数组泛型
            return (Class) ((GenericArrayType) genericClass).getGenericComponentType();
        } else if (genericClass instanceof TypeVariable) { // 处理泛型擦拭对象
            return getClass(((TypeVariable) genericClass).getBounds()[0], 0);
        } else {
            return (Class) genericClass;
        }
    }


    /**
     * 类泛型的表示
     */
    private static class ClassGeneric {
        /**
         * 父类泛型
         */
        private ClassGeneric parent;
        /**
         * 泛型颗粒List
         */
        private List genericList;

        public ClassGeneric getParent() {
            return parent;
        }

        public ClassGeneric setParent(ClassGeneric parent) {
            this.parent = parent;
            return this;
        }

        public List getGenericList() {
            return genericList;
        }

        public ClassGeneric setGenericList(List genericList) {
            this.genericList = genericList;
            return this;
        }

        @Override
        public String toString() {
            return "ClassGeneric{" +
                "parent=" + parent +
                ", genericList=" + genericList +
                '}';
        }
    }

    /**
     * 泛型颗粒
     */
    public static class Generic {

        /**
         * 泛型本身类型
         */
        private String type;

        /**
         * 泛型里面嵌套的泛型
         */
        private ClassGeneric embedClassGeneric;

        public String getType() {
            return type;
        }

        public Generic setType(String type) {
            this.type = type;
            return this;
        }

        public ClassGeneric getEmbedClassGeneric() {
            return embedClassGeneric;
        }

        public Generic setEmbedClassGeneric(ClassGeneric embedClassGeneric) {
            this.embedClassGeneric = embedClassGeneric;
            return this;
        }

        @Override
        public String toString() {
            return "Generic{" +
                "type='" + type + '\'' +
                ", embedClassGeneric=" + embedClassGeneric +
                '}';
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy