package org.test4j.tools.generic; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; /** * 泛型对应的具体类型查找类 * * @author darui.wudr 2013-10-30 下午2:04:16 */ @SuppressWarnings("rawtypes") public class GenericTypeFinder { public static GenericTypeMap findGenericTypes(Type type) { GenericTypeMap map = new GenericTypeMap(); fillInterfaceTypes(type, map); return map; } private static void fillInterfaceTypes(Type type, GenericTypeMap typeMap) { while (type != null && !Object.class.equals(type)) { Class raw = fillTypeGenericType(type, typeMap); Type[] interfaces = raw.getGenericInterfaces(); for (Type _interface : interfaces) { fillInterfaceTypes(_interface, typeMap); } type = raw.getGenericSuperclass(); } } private static Type[] getTypeArgs(Type type) { if (type instanceof Class) { return new Type[0]; } if (type instanceof ParameterizedType) { return ((ParameterizedType) type).getActualTypeArguments(); } if (type instanceof GenericArrayType) { } // if (type instanceof WildcardType) { // // } return new Type[0]; } private static Class getRawType(Type type) { if (type instanceof Class) { return (Class) type; } if (type instanceof ParameterizedType) { return (Class) ((ParameterizedType) type).getRawType(); } if (type instanceof GenericArrayType) { } // if (type instanceof WildcardType) { // // } return Object.class; } private static Class fillTypeGenericType(Type type, GenericTypeMap map) { Class raw = getRawType(type); Type[] args = getTypeArgs(type); TypeVariable[] vars = raw.getTypeParameters(); int index = 0; for (Type arg : args) { if (arg instanceof TypeVariable) { map.putGeneric(vars[index], (TypeVariable) arg); } else { map.putType(vars[index], arg); } index++; } return raw; } }