获取子类用于扩展通用基类的实际类型参数。
//package com.nowjava; import java.lang.reflect.*; import java.util.ArrayList; /* *来 自 时 代 J a v a 公 众 号 */ import java.util.HashMap; import java.util.List; import java.util.Map; public class Main { /** * Get the actual type arguments a child class has used to extend a generic * base class. * * @param baseClass * the base class * @param childClass * the child class * @return a list of the raw classes for the actual type arguments. */ public static <T> List<Class<?>> getTypeArguments( final Class<T> baseClass, final Class<? extends T> childClass) { /** 来 自 n o w j a v a . c o m - 时 代 Java **/ final Map<Type, Type> resolvedTypes = new HashMap<Type, Type>(); Type type = childClass; // start walking up the inheritance hierarchy until we hit baseClass while (!getClass(type).equals(baseClass)) if (type instanceof Class) type = ((Class<?>) type).getGenericSuperclass(); else { final ParameterizedType parameterizedType = (ParameterizedType) type; final Class<?> rawType = (Class<?>) parameterizedType .getRawType(); final Type[] actualTypeArguments = parameterizedType .getActualTypeArguments(); final TypeVariable<?>[] typeParameters = rawType .getTypeParameters(); for (int i = 0; i < actualTypeArguments.length; i++) resolvedTypes.put(typeParameters[i], actualTypeArguments[i]); if (!rawType.equals(baseClass)) type = rawType.getGenericSuperclass(); } // finally, for each actual type argument provided to baseClass, determine (if possible) // the raw class for that type argument. Type[] actualTypeArguments; if (type instanceof Class) actualTypeArguments = ((Class<?>) type).getTypeParameters(); else actualTypeArguments = ((ParameterizedType) type) .getActualTypeArguments(); final List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>(); // resolve types by chasing down type variables. for (Type baseType : actualTypeArguments) { while (resolvedTypes.containsKey(baseType)) baseType = resolvedTypes.get(baseType); typeArgumentsAsClasses.add(getClass(baseType)); } return typeArgumentsAsClasses; } /** * Get the underlying class for a type, or null if the type is a variable * type. * * @param type * the type * @return the underlying class */ public static Class<?> getClass(final Type type) { if (type instanceof Class) return (Class<?>) type; else if (type instanceof ParameterizedType)