获取类或接口中的泛型

获取class的泛型.png
获取interface的泛型.png

工具类

public class GenericUtil {

    /**
     * 确定类在指定位置的泛型Class
     * 注意:匿名内部内要找到泛型,需要在实例化时在后面加{}
     *
     * @param clz            当前类
     * @param finalSupperClz 泛型最高父类
     * @param index          泛型在最高父类泛型中的位置
     * @param <T>
     * @return 泛型类
     * @throws IndexOutOfBoundsException
     * @throws ClassCastException
     * @throws IllegalArgumentException
     */
    public static <T> Class<T> getGenericClass(Class clz, Class finalSupperClz, int index) {
        return getGenericClass(clz, finalSupperClz.getName(), index);
    }

    public static <T> Class<T> getGenericClass(Class clz, String name, int index) {
        if (clz.getName().equals(name)) {
            //已经到需要的最顶级父类了,还是没找到泛型
            //不是泛型类,或者匿名内部内实现后面没带{}
            return null;
        }
        Type genericSuperclass = clz.getGenericSuperclass();
        if (!(genericSuperclass instanceof ParameterizedType)) {
            //当前类的父类没有泛型,去父类的父类中找
            return getGenericClass(clz.getSuperclass(), name, index);
        }
        ParameterizedType type = (ParameterizedType) genericSuperclass;
        String rawName = type.getRawType().getTypeName();
        if (!(rawName.equals(name))) {
            //父类名称不对,去父类的父类去找
            return getGenericClass(clz.getSuperclass(), name, index);
        }

        Type[] actualTypes = type.getActualTypeArguments();
        if (actualTypes.length <= index) {
            //泛型中,没有指定类型的泛型
            return null;
        }

        //由于泛型擦除,这里的强转即使类型不对也不会报错,但是在使用的时候就会报ClassCastException
        //所以在使用时看到这个错误,要去检查一下,对应index的泛型是不是写错了
        return (Class<T>) actualTypes[index];
    }

    /**
     * 确定接口实现类的指定位置泛型类
     */
    public static <T> Class<T> getGenericInterface(Class clz, Class interfaceClz, int index) {
        return getGenericInterface(clz, interfaceClz.getName(), index);
    }

    /**
     * 确定接口实现类的指定位置泛型类
     */
    public static <T> Class<T> getGenericInterface(Class clz, String name, int index) {
        if (clz.getName().equals(Object.class.getName())) {
            throw null;
        }

        Type[] genericInterfaces = clz.getGenericInterfaces();
        if (genericInterfaces.length <= index) {
            //当前类泛型数量小于index,去父类找
            return getGenericInterface(clz.getSuperclass(), name, index);
        }

        for (Type genericInterface : genericInterfaces) {
            if (genericInterface instanceof ParameterizedType) {
                if (((ParameterizedType) genericInterface).getRawType().getTypeName().equals(name)) {
                    return (Class<T>) ((ParameterizedType) genericInterface).getActualTypeArguments()[0];
                }
            }
        }

        return getGenericInterface(clz.getSuperclass(), name, index);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容