20230602 反射中的泛型信息

介绍

Java 泛型的突出特性之一是在虚拟机中擦除泛型类型,但是擦除的类仍然保留原先泛型的一些微弱记忆。例如,原始 Pair 类知道它源自于泛型类 Pair<T> ,尽管无法区分是 Pair<String> 还是 Pair<Integer>

为了描述泛型类型声明,java.lang.reflect 包中提供了接口 Type ,包含以下子类型:

  • Class 类,描述具体类型
  • TypeVariable 接口,描述类型变量(如 T extends Comparable<? super T> )
  • WildcardType 接口, 描述通配符 (如 ? super T )
  • ParameterizedType 接口, 描述泛型类或接口类型(如 Comparable<? super T> )
  • GenericArrayType 接口, 描述泛型数组(如 T[]

后四个类型是接口,虚拟机会实例化实现这些接口的适当的类

获取 Type

java.lang.Class

  • getTypeParameters
    • TypeVariable<Class<T>>[] getTypeParameters()
    • 如果这个类型声明为泛型类型,则获得泛型类型变量
  • getGenericSuperclass
    • Type getGenericSuperclass()
    • 获得这个类型所声明超类的泛型类型
  • getGenericInterfaces
    • Type[] getGenericInterfaces()
    • 获得这个类型所声明接口的泛型类型

java.lang.reflect.Method

  • getTypeParameters
    • TypeVariable<Method>[] getTypeParameters()
  • getGenericReturnType
    • Type getGenericReturnType()
    • 获得这个方法声明的泛型返回类型
  • getGenericParameterTypes
    • Type[] getGenericParameterTypes()
    • 获得这个方法声明的泛型参数类型

java.lang.reflect.Type

介绍

  • java.lang.reflect.Type
  • public interface Type
  • 父接口

API

default

  • getTypeName

java.lang.reflect.TypeVariable

介绍

  • java.lang.reflect.TypeVariable
  • public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement

API

  • getBounds
    • Type[] getBounds();
    • 获得这个类型变量的子类限定
  • getAnnotatedBounds
    • AnnotatedType[] getAnnotatedBounds();
    • 获得这个类型变量的子类限定上的注解信息
  • getName
  • getGenericDeclaration
    • D getGenericDeclaration();
    • 获得这个类型变量的泛型声明

java.lang.reflect.WildcardType

介绍

  • java.lang.reflect.WildcardType
  • public interface WildcardType extends Type

API

  • getUpperBounds
    • Type[] getUpperBounds();
    • 获得这个类型变量的子类(extends)限定
  • getLowerBounds
    • Type[] getLowerBounds();
    • 获得这个类型变量的超类(super)限定

java.lang.reflect.ParameterizedType

介绍

  • java.lang.reflect.ParameterizedType
  • public interface ParameterizedType extends Type
  • 参数化类型,例如 Collection<String>

API

  • getActualTypeArguments
    • Type[] getActualTypeArguments();
    • 获得这个参数化类型声明的类型参数
  • getRawType
    • Type getRawType();
    • 获得这个参数化类型的原始类型
  • getOwnerType
    • Type getOwnerType();
    • 如果是内部类型,返回其外部类型;如果是一个顶级类型,返回 null

java.lang.reflect.GenericArrayType

介绍

  • java.lang.reflect.GenericArrayType
  • public interface GenericArrayType extends Type

API

  • getGenericComponentType
    • Type getGenericComponentType();
    • 获得这个数组类型声明的泛型元素类型

代码示例

示例一

public class TestTypeVariable<T extends Number & Comparable<? super T>> {


    public static void main(String[] args) {
        Class<TestTypeVariable> testTypeVariableClass = TestTypeVariable.class;
        TypeVariable<Class<TestTypeVariable>>[] typeParameters = testTypeVariableClass.getTypeParameters();

        for (TypeVariable<Class<TestTypeVariable>> typeParameter : typeParameters) {
            System.out.println("typeParameter :: " + typeParameter);
            System.out.println("typeParameter.getClass() :: " + typeParameter.getClass());

            Class<TestTypeVariable> genericDeclaration = typeParameter.getGenericDeclaration();
            System.out.println("typeParameter.getGenericDeclaration() :: " + genericDeclaration);



            Type[] bounds = typeParameter.getBounds();
            for (int i = 0; i < bounds.length; i++) {
                Type bound = bounds[i];
                System.out.println("====================== i = " + i);
                System.out.println("bound :: " + bound);
                System.out.println("bound.getClass() :: " + bound.getClass());

                if (bound instanceof ParameterizedType parameterizedType) {
                    Type rawType = parameterizedType.getRawType();
                    System.out.println("rawType :: " + rawType);
                    System.out.println("rawType.getClass() :: " + rawType.getClass());

                    System.out.println("parameterizedType.getOwnerType() :: " + parameterizedType.getOwnerType());

                    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                    for (int j = 0; j < actualTypeArguments.length; j++) {
                        Type actualTypeArgument = actualTypeArguments[j];
                        System.out.println("-------------- j = " + j);
                        System.out.println("actualTypeArgument :: " + actualTypeArgument);
                        System.out.println("actualTypeArgument.getClass() :: " + actualTypeArgument.getClass());

                        if (actualTypeArgument instanceof WildcardType wildcardType) {
                            Type[] lowerBounds = wildcardType.getLowerBounds();
                            Type[] upperBounds = wildcardType.getUpperBounds();

                            System.out.println("lowerBounds :: " + Arrays.toString(lowerBounds));
                            System.out.println("upperBounds :: " + Arrays.toString(upperBounds));
                        }
                    }
                }
            }
        }
    }
}

输出结果

typeParameter :: T
typeParameter.getClass() :: class sun.reflect.generics.reflectiveObjects.TypeVariableImpl
typeParameter.getGenericDeclaration() :: class study.hwj.v1p8.generic.TestTypeVariable
====================== i = 0
bound :: class java.lang.Number
bound.getClass() :: class java.lang.Class
====================== i = 1
bound :: java.lang.Comparable<? super T>
bound.getClass() :: class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
rawType :: interface java.lang.Comparable
rawType.getClass() :: class java.lang.Class
parameterizedType.getOwnerType() :: null
-------------- j = 0
actualTypeArgument :: ? super T
actualTypeArgument.getClass() :: class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl
lowerBounds :: [T]
upperBounds :: [class java.lang.Object]

示例二

public class TestGeneric<T> {

    public TestGeneric() {
        Type type = getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType parameterizedType) {
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println("actualTypeArgument.getClass() :: " + actualTypeArgument.getClass());
                if (actualTypeArgument instanceof ParameterizedType parameterizedType1) {
                    Type[] actualTypeArguments1 = parameterizedType1.getActualTypeArguments();
                    System.out.println("getActualTypeArguments :: " + Arrays.toString(actualTypeArguments1));

                    Type rawType = parameterizedType1.getRawType();
                    System.out.println("rawType :: " + rawType);

                } else {
                    System.out.println("actualTypeArgument :: " + actualTypeArgument);
                }
            }
        }
    }

    public static void main(String[] args) {
        TestGeneric<List<String>> testGeneric = new TestGeneric<>() {
        };  // TestGeneric 的匿名子类
        System.out.println(testGeneric.getClass());

        System.out.println("========================");

        TestGeneric<String> testGeneric2 = new TestGeneric<>();     // TestGeneric 类
        System.out.println(testGeneric2);


    }
}

输出结果

actualTypeArgument.getClass() :: class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
getActualTypeArguments :: [class java.lang.String]
rawType :: interface java.util.List
class study.hwj.v1p8.TestGeneric$1
========================
study.hwj.v1p8.TestGeneric@52cc8049
posted @ 2023-09-05 09:26  流星<。)#)))≦  阅读(6)  评论(0编辑  收藏  举报