基础知识

如何获取泛型类的子类中声明的泛型类型

2018-02-05  本文已影响0人  李北北

标题好绕啊,还是直接用代码说话比较好。

1、泛型父类Parent源码

package com.xxx.xxx.util;

/**
 * 父类
 * @author 北北
 * @date 2018年2月5日下午2:03:02
 */
public class Parent<M, E> {

}

2、声明泛型的子类Children源码

package com.xxx.xxx.util;

import com.xxx.xxx.model.basics.User;
import com.xxx.xxx.model.basics.UserExample;

/**
 * 子类
 * @author 北北
 * @date 2018年2月5日下午2:03:22
 */
public class Children extends Parent<User, UserExample> {
    
}

问题描述

到了这里就比较方便说明问题了,我们定义了泛型类Parent,并且定义了一个子类Children并且声明泛型参数M、E的值分别是BasicsUsers、BasicsUsersExample类,我们需要通过Children类或者其对象获取到已经声明的泛型类型BasicsUsers、BasicsUsersExample。

要怎么做呢?
这里就需要用到反射了。

3、获取声明的泛型类的方法,代码如下

package com.xxx.xxx.util;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class ReflectUtil {
    
    /**
     * 根据泛型类的已经声明泛型类型的子类获取指定位置的泛型
     * @author 北北
     * @date 2018年1月18日上午11:34:59
     * @param clazz -- 当前类
     * @param index -- 第几个泛型, 从0开始
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> getGenericClass(Class<T> clazz, Integer index) {
        if(clazz == null){
            return null;
        }
        if(index == null){
            index = 0;
        }
        
        //提取泛型类数组
        ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass(); 
        Type[] genericTypes = parameterizedType.getActualTypeArguments();
        
        //越界判断
        if((index+1) > genericTypes.length){
            return null;
        }
        Class<T> retClass= (Class<T>) genericTypes[index];
        return retClass; 
    }
    
}

4、测试代码及运行结果,下面根据子类本身及其实例化对象测试

public static void main(String[] args) {
        Class<?> clazz1 = ReflectUtil.getGenericClass(Children.class, 0);
        Class<?> clazz2 = ReflectUtil.getGenericClass(Children.class, 1);
        System.out.println("类名称获取, 第一个泛型类:" + clazz1);
        System.out.println("类名称获取, 第二个泛型类:" + clazz2);
        
        Children children = new Children();
        Class<?> clazz3 = ReflectUtil.getGenericClass(children.getClass(), 0);
        Class<?> clazz4 = ReflectUtil.getGenericClass(children.getClass(), 1);
        System.out.println("对象获取, 第一个泛型类:" + clazz3);
        System.out.println("对象获取, 第一个泛型类:" + clazz4);
}

运行结果:


image.png

注意

需要注意的是,通过这种方法只能获得泛型类的子类中声明的泛型类型,不能获得泛型接口的实现类声明的泛型类型。
对于这个问题,这里有一个可行的解决办法是,先定义一个泛型类继承泛型接口,然后再让你的子类继承这个泛型类并且声明泛型类型。

上一篇 下一篇

猜你喜欢

热点阅读