针对泛型中复杂类型该怎么解析,这就需要考虑泛型的各种形式:
如:
public static <T extends Comparable<? super T>> Pair<T> minmax(T[] arr);
public static <T extends Comparable&Serializable> T min(T... a);
那么有必要使用自定的泛型的工具类的了、
package com.easyway.commons.ispace.dev.advances.generics; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; /** * 泛型类型的解析 * @author longgangbai * @date 2010-5-20 * @version 1.0 * @since JDK6.0 */ public abstract class GenericTypeResolver { private GenericTypeResolver() { } /** * 解析一个泛型方法的返回值 * @param method * @param clazz * @return */ public static Class resolveReturnType(Method method, Class clazz) { Type genericType = method.getGenericReturnType(); Map typeVariableMap = getTypeVariableMap(clazz); Type rawType = getRawType(genericType, typeVariableMap); return (rawType instanceof Class) ? (Class)rawType : method.getReturnType(); } /** * * @param genericType * @param typeVariableMap * @return */ public static Class resolveType(Type genericType, Map typeVariableMap) { Type rawType = getRawType(genericType, typeVariableMap); return (rawType instanceof Class) ? (Class)rawType : java.lang.Object.class; } /** * * @param genericType * @param typeVariableMap * @return */ public static Type getRawType(Type genericType, Map typeVariableMap) { Type resolvedType = genericType; if(genericType instanceof TypeVariable) { TypeVariable tv = (TypeVariable)genericType; resolvedType = (Type)typeVariableMap.get(tv); if(resolvedType == null) resolvedType = extractBoundForTypeVariable(tv); } if(resolvedType instanceof ParameterizedType) return ((ParameterizedType)resolvedType).getRawType(); else return resolvedType; } /** * 获取对象反省的 所有参数类型 * @param clazz * @return */ public static Map getTypeVariableMap(Class clazz) { Map typeVariableMap = (Map)typeVariableCache.get(clazz); if(typeVariableMap == null) { typeVariableMap = new HashMap(); extractTypeVariablesFromGenericInterfaces(clazz.getGenericInterfaces(), typeVariableMap); Type genericType = clazz.getGenericSuperclass(); for(Class type = clazz.getSuperclass(); type != null && !(java.lang.Object.class).equals(type); type = type.getSuperclass()) { if(genericType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType)genericType; populateTypeMapFromParameterizedType(pt, typeVariableMap); } extractTypeVariablesFromGenericInterfaces(type.getGenericInterfaces(), typeVariableMap); genericType = type.getGenericSuperclass(); } for(Class type = clazz; type.isMemberClass(); type = type.getEnclosingClass()) { genericType = type.getGenericSuperclass(); if(genericType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType)genericType; populateTypeMapFromParameterizedType(pt, typeVariableMap); } } typeVariableCache.put(clazz, typeVariableMap); } return typeVariableMap; } /** * 泛型中范围限制类型那个的解析 TypeVariable<D extends GenericDeclaration> * @param typeVariable * @return */ public static Type extractBoundForTypeVariable(TypeVariable typeVariable) { Type bounds[] = typeVariable.getBounds(); if(bounds.length == 0) return java.lang.Object.class; Type bound = bounds[0]; if(bound instanceof TypeVariable) bound = extractBoundForTypeVariable((TypeVariable)bound); return bound; } /** * 泛型接口的使用 * @param genericInterfaces * @param typeVariableMap */ public static void extractTypeVariablesFromGenericInterfaces(Type genericInterfaces[], Map typeVariableMap) { for(int i = 0; i < genericInterfaces.length; i++) { Type genericInterface = genericInterfaces[i]; if(genericInterface instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType)genericInterface; populateTypeMapFromParameterizedType(pt, typeVariableMap); if(pt.getRawType() instanceof Class) extractTypeVariablesFromGenericInterfaces(((Class)pt.getRawType()).getGenericInterfaces(), typeVariableMap); continue; } if(genericInterface instanceof Class) extractTypeVariablesFromGenericInterfaces(((Class)genericInterface).getGenericInterfaces(), typeVariableMap); } } private static void populateTypeMapFromParameterizedType(ParameterizedType type, Map typeVariableMap) { if(type.getRawType() instanceof Class) { Type actualTypeArguments[] = type.getActualTypeArguments(); TypeVariable typeVariables[] = ((Class)type.getRawType()).getTypeParameters(); for(int i = 0; i < actualTypeArguments.length; i++) { Type actualTypeArgument = actualTypeArguments[i]; TypeVariable variable = typeVariables[i]; if(actualTypeArgument instanceof Class) { typeVariableMap.put(variable, actualTypeArgument); continue; } if(actualTypeArgument instanceof GenericArrayType) { typeVariableMap.put(variable, actualTypeArgument); continue; } if(actualTypeArgument instanceof ParameterizedType) { typeVariableMap.put(variable, actualTypeArgument); continue; } if(!(actualTypeArgument instanceof TypeVariable)) continue; TypeVariable typeVariableArgument = (TypeVariable)actualTypeArgument; Type resolvedType = (Type)typeVariableMap.get(typeVariableArgument); if(resolvedType == null) resolvedType = extractBoundForTypeVariable(typeVariableArgument); typeVariableMap.put(variable, resolvedType); } } } private static final Map typeVariableCache = Collections.synchronizedMap(new WeakHashMap()); }