java 反射泛型工具类, 获取类的泛型类型

2023-11-16

直接上代码

public class ParameterizedTypeUtils {

    /**
     * 根据索引获取泛型实例类
     *
     * @param type  类型
     * @param index
     * @return java.lang.Class<?>
     */
    public static Type get(Type type, int index) {
        ParameterizedType aClass = (ParameterizedType) type;
        Type[] actualTypes = aClass.getActualTypeArguments();
        return actualTypes[index];
    }
}

Api

带泛型的属性值 Field.getGenericType
带泛型的方法返回值 Method.getGenericReturnType
带泛型的父类 Class.getGenericSuperclass
带泛型的接口集合 Class.getGenericInterfaces

例子

获取不涉及泛型的返回值以及属性值

    List<Integer> list1 = new ArrayList<>();

    List<Integer[]> list2 = new ArrayList<>();

    List<List<Integer>> list3 = new ArrayList<>();

    List<String> test(){
        return null;
    }

    List<Map<String,Object>> testMap(){
        return null;
    }

    @Test
    public void typeTest() throws NoSuchFieldException, NoSuchMethodException {
        Type list1 = this.getClass().getDeclaredField("list1").getGenericType();
        Type list2 = this.getClass().getDeclaredField("list2").getGenericType();
        Type list3 = this.getClass().getDeclaredField("list3").getGenericType();
        Type test = this.getClass().getDeclaredMethod("test").getGenericReturnType();
        Type testMap = this.getClass().getDeclaredMethod("testMap").getGenericReturnType();

        Type type1 = ParameterizedTypeUtils.get(list1, 0);
        Type type2 = ParameterizedTypeUtils.get(list2, 0);
        Type type3 = ParameterizedTypeUtils.get(list3, 0);
        Type testType= ParameterizedTypeUtils.get(test, 0);
        Type typeMapType = ParameterizedTypeUtils.get(testMap, 0);

        System.out.println(type2.getClass() + " : "+type1);
        System.out.println(type2.getClass() + " : "+type2.getTypeName());
        System.out.println(type3.getClass() + " : "+type3);
        System.out.println(testType.getClass() + " : "+testType);
        System.out.println(typeMapType.getClass() + " : "+typeMapType);

    }
}

输出 :

class java.lang.Class : class java.lang.Integer
class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl : java.util.List<java.lang.Integer>
class java.lang.Class : class java.lang.String
class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl : java.util.Map<java.lang.String, java.lang.Object>

这里注意,第二个和第四个的返回值又是一个泛型Type,属于泛型中的泛型类 ParameterizedTypeImpl,并不是 Class ,如果直接强转为 Class<?> 会报错

System.out.println((Class<?>)ParameterizedTypeUtils.get( testMap , 0)); // 报错

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class

涉及泛型

public class Main<T,E>  {

    List<? extends  T> list = new ArrayList<>();

    List<T> list1 = new ArrayList<>();

    List<T[]> list2 = new ArrayList<>();

    List<List<T>> list3 = new ArrayList<>();

    List<T> test(){
        return null;
    }

    List<Map<String,T>> testMap(){
        return null;
    }

    @Test
    public void typeTest() throws NoSuchFieldException, NoSuchMethodException {

		System.out.println(Arrays.toString(this.getClass().getTypeParameters()));

        Type list = this.getClass().getDeclaredField("list").getGenericType();
        Type list1 = this.getClass().getDeclaredField("list1").getGenericType();
        Type list2 = this.getClass().getDeclaredField("list2").getGenericType();
        Type list3 = this.getClass().getDeclaredField("list3").getGenericType();
        Type test = this.getClass().getDeclaredMethod("test").getGenericReturnType();
        Type testMap = this.getClass().getDeclaredMethod("testMap").getGenericReturnType();

        Type type  = ParameterizedTypeUtils.get(list  , 0);
        Type type1 = ParameterizedTypeUtils.get(list1, 0);
        Type type2 = ParameterizedTypeUtils.get(list2, 0);
        Type type3 = ParameterizedTypeUtils.get(list3, 0);
        Type testType= ParameterizedTypeUtils.get(test, 0);
        Type typeMapType = ParameterizedTypeUtils.get(testMap, 0);

        System.out.println(type.getClass() + " : "+type);
        System.out.println(type2.getClass() + " : "+type1);
        System.out.println(type2.getClass() + " : "+type2.getTypeName());
        System.out.println(type3.getClass() + " : "+type3);
        System.out.println(testType.getClass() + " : "+testType);
        System.out.println(typeMapType.getClass() + " : "+typeMapType);

    }
}

输出:

[T, E]
class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl : ? extends T
class sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl : T
class sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl : T[]
class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl : java.util.List<T>
class sun.reflect.generics.reflectiveObjects.TypeVariableImpl : T
class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl : java.util.Map<java.lang.String, T>

获取父类上面的泛型注解

getGenericSuperclass

class Father{ }
class Son{ }
class Person<T>{ }
class XiaoMing extends Person<Son> { }
class ZhangSan extends Person<Father>{ }
System.out.println(ParameterizedTypeUtils.get(ZhangSan.class.getGenericSuperclass(), 0) );
System.out.println(ParameterizedTypeUtils.get(XiaoMing.class.getGenericSuperclass(), 0) );
class Father
class Son

获取实现接口上面的泛型注解

getGenericInterfaces

class Father{ }
class Son{ }
interface Person<T>{ }
class XiaoMing implements Person<Son> { }
class ZhangSan implements Person<Father>{ }
System.out.println(ParameterizedTypeUtils.get(ZhangSan.class.getGenericInterfaces()[0], 0) );
System.out.println(ParameterizedTypeUtils.get(XiaoMing.class.getGenericInterfaces()[0], 0) );
class Father
class Son

不要获取未实例化对象的类的泛型,会直接得出泛型本身
例如泛型为 T, 那也只能获取到 T,不会是某个具体类型。

class A<T>{}
ParameterizedTypeUtils.get(A.class,0) // T
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 反射泛型工具类, 获取类的泛型类型 的相关文章

  • Intellij Idea:导入Gradle项目-尚未定义JAVA_HOME

    Intellij 理念 14 1 4 Mac OS X Yosemite 10 10 3 及更高版本 从 IDE Import Project gt Chosen directory to import gt Import project
  • Import 语句顺序有什么影响吗?

    这个疑问由来已久 当我使用 eclipse 编写类时 导入语句会自动填充 import语句的顺序有影响吗 1 关于编程执行速度 2 任何标准编码实践都是相同的 import语句对执行速度没有影响at all 它们仅在编译时重要 如果您完全限
  • JAVA GENERICS错误:具有相同的擦除,但两者都没有覆盖另一个[重复]

    这个问题在这里已经有答案了 为了好玩 我正在创建一个排序框架 以更好地理解各种排序算法 而且 我试图使其足够通用 以便它可以对实现扩展可比较接口的接口的任何内容进行排序 然而 java 编译器对我不满意 这是我的界面 public inte
  • 翻转旋转和图像

    我正在用 Java 编写一个平台游戏 并且正在手动编码玩家动画 我分别为每个肢体设置动画 改变位置和旋转 当玩家面向右时 这工作得很好 但是当玩家面向左时 我不知道如何处理旋转 以使它们在玩家向左转时看起来相同 每个身体部位的位置都是相对于
  • JAR 清单代码库不匹配

    我在 dropbox 中有一个小程序 在 droppages 中有一个链接 该小程序是自签名的 按照代码操作 Manifest Version 1 0 Ant Version Apache Ant 1 9 1 X COMMENT Main
  • java:查找数组中整数的频率

    我需要开发一个java要求用户输入一些内容的程序integers并找出最大和最小的数 以及这些数的平均值 然后 划分数组的集合分成若干子区间用户指定的 然后它生成一个边界点 每个边界点的长度为子区间宽度 问题是我需要创建一个频率 例如 间隔
  • Hibernate/JPA 在启动时不验证数据库架构

    由于某种原因 hibernate 无法捕获诸如将实体映射到不存在的表之类的问题 我的 persistence xml 文件看起来像这样
  • 相机 java.lang.RuntimeException:setParameters 失败

    我使用创建了一个自定义相机应用程序this https github com davidgatti dgCam源代码 但在少数设备上 例如高分辨率设备 我得到 RuntimeException setParameters failed 我面
  • 如何解决 MongoWaitQueueFullException?

    我运行一个java程序 它是一个线程执行程序 它将数千个文档插入到mongodb中的表中 我收到以下错误 Exception in thread pool 1 thread 301 com mongodb MongoWaitQueueFul
  • 原生状态栏

    有没有办法创建nativeSWT 中的状态栏与 Windows 应用程序中的状态栏类似 我见过使用标签模拟的状态栏 但我对真正的解决方案更感兴趣 org eclipse jface action StatusLineManager crea
  • 如何使用 Jackson 重命名 JSON 序列化中的根密钥

    我正在使用 Jackson 对对象列表进行 JSON 序列化 这是我得到的 ArrayList id 1 name test name 但我想要这个 rootname id 1 name test name ie showing the s
  • 能够存储微秒的 Date 对象

    我正在寻找一个能够存储到微秒粒度的 Date 对象 有人知道吗 标准Date对象仅存储到毫秒 我知道这是平台限制 我可以通过包装来解决这个问题Date加上自定义类别中的小数数量 然而 我希望避免编写一个带有适当计算等的内容 我需要解析一个b
  • Struts 2 中的 Java 应用程序可以管理多少个会话?

    我正在开发事务管理应用程序 并且正在使用 Struts2 我在内部使用了一个会话来设置和获取值 例如 ActionContext getContext getSession put string string 在应用程序中使用这样的会话是否
  • Java:删除链表中的所有元素

    Java中如何删除链表中的所有元素without使用已经可用的clear 方法 这项练习的灵感来自于电话采访中收到的一个问题 说我可以用 C 来做这个 void DeleteAllElement ListElement head ListE
  • 使用 Android 将文本文件上传到 Google Drive

    编辑 我已将文本设置为字符串 如下所示 字符串文本 你好 我想将其转换为纯文本文件 然后上传到 Google 云端硬盘文件夹 我已经尝试过下面的代码 但它不完整 所以我无法说出出现了什么错误 我正在使用 Google Drive 快速启动
  • 从 Java 读取 /dev/input/js0

    我正在尝试阅读 dev input js0来自Java 但我不断得到 java io IOException Invalid argument at java io FileInputStream read0 Native Method a
  • 如何在 SnakeYaml 中解析 YAML 文件的一部分

    我是 YAML 新手 并且解析了一个 YAML 配置文件 如下所示 applications authentication service version 2 0 service url https myapp corp auth app
  • Java 中的 ConcurrentHashMap 和 Hashtable [重复]

    这个问题在这里已经有答案了 Java 中的 ConcurrentHashMap 和 Hashtable 有什么区别 哪个对于线程应用程序更有效 ConcurrentHashMap 和 Hashtable 锁定机制 Hashtable属于Co
  • TextView 用字母打乱了我的话

    我的要求 创建 传入气泡 其宽度按内容排列 最大宽度为 90 我有这个标记
  • 在java中使用共享密钥加密/解密?

    我有客户令牌 我正在从一个 Web 应用程序 如 app1 发送到另一个 Web 应用程序 如 app2 我想加密客户令牌 在 app1 上 并使用在 app1 和 app2 上共享的密钥在 app2 上对其进行解密 我不知道如何开始 这将

随机推荐