针对泛型中复杂类型该怎么解析,这就需要考虑泛型的各种形式:
如:
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());
}