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

直接上代码

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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java 反射工具类 ReflectUtils 是一个提供了便捷的反射操作方法的工具类。它封装了 Java 反射 API 的一些常用功能,使得开发者能够更加方便地使用反射进行类、方法、字段的操作。 ReflectUtils 提供了以下几个方法: 1. getTypeArguments:通过反射获取指定类的类型参数。可以通过该方法来获取类型的具体参数类型,方便在运行时进行类型判断和操作。 2. invokeGetter:通过反射调用指定对象的指定字段的 getter 方法。在无法直接访问字段或需要动态调用字段的 getter 方法时,可以使用该方法。 3. invokeSetter:通过反射调用指定对象的指定字段的 setter 方法。在无法直接访问字段或需要动态调用字段的 setter 方法时,可以使用该方法。 4. getFieldValue:通过反射获取指定对象的指定字段的值。在无法直接访问字段时,可以使用该方法获取字段的值。 5. setFieldValue:通过反射设置指定对象的指定字段的值。在无法直接访问字段时,可以使用该方法设置字段的值。 6. getField:通过反射获取指定类的指定字段。可以用于获取字段的修饰符、类型等信息。 7. getMethod:通过反射获取指定类的指定方法。可以用于获取方法的修饰符、返回值类型、参数类型等信息。 ReflectUtils 的使用能够简化反射操作的代码,提高开发效率,但也需要注意合理使用,避免引入不必要的复杂性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值