介绍
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
标签:lang,反射,java,System,println,泛型,out,Type,20230602
From: https://www.cnblogs.com/huangwenjie/p/17545289.html