美文网首页基础知识
如何获取泛型类的子类中声明的泛型类型

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

作者: 李北北 | 来源:发表于2018-02-05 16:28 被阅读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

注意

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

相关文章

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

    标题好绕啊,还是直接用代码说话比较好。 1、泛型父类Parent源码 2、声明泛型的子类Children源码 问题...

  • OC 泛型, __kindof

    泛型:限制类型 泛型声明格式:在声明类的时候,在类型后面<泛型名称>泛型定义格式:放在限制的类型后面<类型> 泛型...

  • [iOS] 泛型ObjectType 协变__covariant

    一.泛型作用 二.泛型用法: 1.泛型声明:在声明类的时候,在类的后面<泛型名称> 2.使用泛型 类型<限制类型>...

  • 43.泛型上限

    泛型上限 泛型智能是Fruit类型或者Fruit类型的子类 泛型的作用:放如何类型 限制存放的类型

  • Java 完美获取泛型类型(包含嵌套的泛型)

    完美获取泛型类型(包含嵌套多层的泛型) 1. 工具类 获取泛型类型工具类 2. 使用方法 2.1. 集成接口带有泛...

  • Kotlin---泛型

    Kotlin不变型泛型 Kotlin的不变型泛型和Java一样,通过声明泛型类型来使用泛型类。而该种泛型声明后,则...

  • 《Effective Java》泛型--请不要在新代码中使用原生

    泛型:声明中具有一个或多个类型参数的类或者接口就是泛型 原生态类型的泛型:不带任何实际参数的泛型名称,例如List...

  • 第23条 请不要在新代码中使用原生态类型

    声明中具有一个或者多个类型参数的类或者接口,就是泛型类或者接口。没有使用泛型的类型就是原生态类型。 每种泛型定义一...

  • 泛型

    1.什么是泛型? 2.为什么需要泛型? 3.泛型类、接口 泛型类注意事项: 从泛型类派生子类 泛型接口 泛型接口的...

  • Scala 泛型以及泛型约束

    泛型类 在类声明时,定义一些泛型类型,然后在类的内部,就可以使用这些泛型类型 在需要对类中的某些成员,如字段或方法...

网友评论

    本文标题:如何获取泛型类的子类中声明的泛型类型

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