Java获取泛型实际类型的方法详解

 更新时间:2023年11月06日 09:54:09   作者:杨小胖要减肥  
这篇文章主要介绍了Java获取泛型实际类型的方法详解,泛型,即“参数化类型”,一提到参数,最熟悉的就是定义方法时有形参列表,普通方法的形参列表中,每个形参的数据类型是确定的,而变量是一个参数,需要的朋友可以参考下

Java反射获取

获取类上的泛型

获取父类定义的泛型

例如现在有一个父类

public abstract class TestClass<E> {
  ......
}

同时他有多个实现类,如

public class TestStringClass extends TestClass<String>{
  ....
}

public class TestIntegerClass extends TestClass<Integer>{
  ....
}
....

此时如果要获取该类上声明的泛型

需要用到Class类中的getGenericSuperclass方法

getGenericSuperclass方法的作用是:

返回该class所表示的实体(类、接口、原始类型或void)的直接父类的Type。如果父类是参数化类型(即有泛型定义),那么返回的Type对象必须准确的反应源代码中使用的实际类型参数。

如果是带有泛型的父类,则会返回ParameterizedType,如果当前Class是Object类,接口,原始类型或者void,则会返回null。

如果此对象表示数组类,则返回表示Object类的Class对象。

ParameterizedType类有3个方法,其中getActualTypeArguments能获取到泛型列表的数组。

那么在父类中,如果要获取子类声明的泛型类型,就可以使用此方法

Type genericSuperclass = this.getClass().getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType){
  ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
  Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
  for (Type actualTypeArgument : actualTypeArguments) {
    System.out.println(actualTypeArgument);
  }
}

如此一来,就可以获取到父类的泛型了。

public abstract class TestClass<E> {

   public void print(){
      Type genericSuperclass = this.getClass().getGenericSuperclass();
      List<Type> list = null;
      if (genericSuperclass instanceof ParameterizedType){
         ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
         Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
         list = Arrays.asList(actualTypeArguments);
      }
      System.out.println(this.getClass() + " 的泛型 = " + list);
   }
}

public class TestStringClass extends TestClass<String>{

    public static void main(String[] args) {
        TestStringClass testStringClass = new TestStringClass();
        testStringClass.print();
    }
}

// class xxx.TestStringClass 的泛型 = [class java.lang.String]

public class TestMapClass extends TestClass<Map<String,String>>{

    public static void main(String[] args) {
        TestMapClass testMapClass = new TestMapClass();
        testMapClass.print();
    }
}

// class xxx.TestMapClass 的泛型 = [java.util.Map<java.lang.String, java.lang.String>]

如果我们想获取泛型中的泛型,例如上面的TestClass<Map<String,String>>中的Map的泛型。

我们可以看到ParameterizedType有很多实现类,其中java原生的实现类为sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl

这个实现类中也有一个actualTypeArguments属性,也就是说,可以继续尝试获取泛型列表

获取接口定义的泛型

很多的接口上也定义了泛型描述,可以通过Class的getGenericInterfaces方法获取,因为一个类可以实现多个接口,所以返回了一个Type数组,可以遍历数组,找到需要处理的接口对应的Type,其余的操作就获取父类上的泛型操作一致了。

获取属性的泛型

获取属性的泛型,先通过Class,获取到需要获取泛型的Field,然后过个Field类的getGenericType方法获取到Type,其余操作与获取父类上的泛型操作一致。

通过Spring工具类获取

spring-core工程中,提供了一个ResolvableType工具类,他可以从属性、方法参数、方法返回、类中后去对应的泛型。从Spring4.0开始提供这个工具类。

常用的方法有

  • forField(Field field) 获取属性的泛型
  • forMethodParameter(Method method, int parameterIndex) 获取方法指定参数的泛型
  • forMethodReturnType(Method method) 获取方法返回值的泛型
  • forConstructorParameter(Constructor constructor, int parameterIndex) 获取构造函数指定参数的泛型
  • forClass(Class clazz) 获取class的泛型
  • forType(Type type) 获取type的泛型
  • forInstance(Object) 通过实体获取泛型

官方示例:

private HashMap<Integer, List<String>> myMap;
 
  public void example() {
      ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
      t.getSuperType(); // AbstractMap<Integer, List<String>>
      t.asMap(); // Map<Integer, List<String>>
    	// 获取指定下标的泛型类型
      t.getGeneric(0).resolve(); // Integer
      t.getGeneric(1).resolve(); // List
      t.getGeneric(1); // List<String>
    	// 获取指定下标的泛型的指定下标的泛型,即获取嵌套泛型的泛型
      t.resolveGeneric(1, 0); // String
  }

到此这篇关于Java获取泛型实际类型的方法详解的文章就介绍到这了,更多相关Java获取泛型实际类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现将json数组转换成对象列表的三种实现方法

    Java实现将json数组转换成对象列表的三种实现方法

    在Java中,将JSON数组转换为对象列表通常需要借助第三方JSON处理库,常用的库包括 Jackson、Gson 和 Fastjson,以下是各库的详细实现步骤,大家可以根据需要进行选择
    2025-12-12
  • Java无法输出中文问题及解决

    Java无法输出中文问题及解决

    这篇文章主要介绍了Java无法输出中文问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Spring组件开发模式支持SPEL表达式

    Spring组件开发模式支持SPEL表达式

    今天小编就为大家分享一篇关于Spring组件开发模式支持SPEL表达式,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • Java spring注解@PostConstruct实战案例讲解

    Java spring注解@PostConstruct实战案例讲解

    我们在Spring项目中经常会遇到@PostConstruct注解,可能有的伙伴对这个注解很陌生,下面这篇文章主要给大家介绍了关于Java spring注解@PostConstruct实战案例讲解的相关资料,需要的朋友可以参考下
    2023-12-12
  • 详解Java中如何使用JFreeChart生成甘特图

    详解Java中如何使用JFreeChart生成甘特图

    甘特图是一种流行的项目管理工具,用于显示项目的进度和任务分配,在Java开发中,JFreeChart是一个强大的开源图表库,能够生成各种类型的图表,下面我们就来看看如何使用JFreeChart生成甘特图吧
    2025-01-01
  • java实现波雷费密码算法示例代码

    java实现波雷费密码算法示例代码

    这篇文章主要介绍了java实现波雷费密码算法示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • SpringBoot中YAML配置文件实例详解

    SpringBoot中YAML配置文件实例详解

    前面一直在使用properties配置文件,spring boot也支持yaml配置文件,下面这篇文章主要给大家介绍了关于SpringBoot中YAML配置文件的相关资料,需要的朋友可以参考下
    2023-04-04
  • JAVA基本类型包装类 BigDecimal BigInteger 的使用

    JAVA基本类型包装类 BigDecimal BigInteger 的使用

    Java 中预定义了八种基本数据类型,包括:byte,int,long,double,float,boolean,char,short,接下来文章小编将向大家介绍其中几个类型的内容,需要的朋友可以参考下文章
    2021-09-09
  • java实现AES可逆加密算法

    java实现AES可逆加密算法

    这篇文章主要为大家详细介绍了java实现AES可逆加密算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • Java反射之通过反射获取一个对象的方法信息(实例代码)

    Java反射之通过反射获取一个对象的方法信息(实例代码)

    下面小编就为大家带来一篇Java反射之通过反射获取一个对象的方法信息(实例代码)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10

最新评论