package jef.tools.reflect; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import jef.common.Entry; import jef.tools.Assert; /** * 泛型工具集,用于解析泛型、生成泛型 * @Company: Asiainfo-Linkage Technologies(China),Inc. Hangzhou * @author Administrator * @Date 2011-6-20 */ public final class GenericUtils{ /** * 泛型类型常量 Map<String,String> */ public static final Type MAP_OF_STRING=newMapType(String.class,String.class); /** * 泛型类型常量 Map<String,String[]> */ public static final Type MAP_STRING_SARRAY=newMapType(String.class,String[].class); /** * 泛型类型常量 Map<String,Object> */ public static final Type MAP_STRING_OBJECT=newMapType(String.class,Object.class); /** * 泛型类型常量 List<String> */ public static final Type LIST_STRING=newListType(String.class); /** * 泛型类型常量 List<Object> */ public static final Type LIST_OBJECT=newListType(Object.class); public static Class<?> getRawClass(Type type) { if (type instanceof Class<?>) { // type is a normal class. return (Class<?>) type; } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; // I'm not exactly sure why getRawType() returns Type instead of // Class. // Neal isn't either but suspects some pathological case related // to nested classes exists. Type rawType = parameterizedType.getRawType(); Assert.isTrue(rawType instanceof Class); return (Class<?>) rawType; } else if (type instanceof GenericArrayType) { Type componentType = ((GenericArrayType) type).getGenericComponentType(); return Array.newInstance(getRawClass(componentType), 0).getClass(); } else if (type instanceof TypeVariable) { // we could use the variable's bounds, but that won't work if there // are multiple. // having a raw type that's more general than necessary is okay return Object.class; } else if (type instanceof WildcardType) { return getRawClass(((WildcardType) type).getUpperBounds()[0]); } else { String className = type == null ? "null" : type.getClass().getName(); throw new IllegalArgumentException("Expected a Class, ParameterizedType, or " + "GenericArrayType, but <" + type + "> is of type " + className); } } /** * Google编写的泛型解析方法 * @param context * @param toResolve * @return */ public static Type resolve2(Type context,Type toResolve){ return GqGenericResolver.resolve(context, context==null?null:getRawClass(context), toResolve); } /** * Jiyi编写的泛型解析方法,将所有泛型边界和泛型边界解析为边界的具体类型 * @param context * @param toResolve * @return */ public static Type resolve (Type context,Type toResolve){ return getBoundType(toResolve, context==null?null:new ClassEx(context)); } /** * Jiyi 编写的计算泛型边界,将泛型变量、边界描述、全部按照允许的最左边界进行计算 * * @param type * @param cw * @return */ public static Type getBoundType(Type type, ClassEx cw) { if (type instanceof TypeVariable<?>) { TypeVariable<?> tv = (TypeVariable<?>) type; Type real = cw.getImplType(tv); if (real != null) { return getBoundType(real, cw); } real = tv.getBounds()[0]; return getBoundType(real, cw); } else if (type instanceof WildcardType) { WildcardType wild = (WildcardType) type; return getBoundType(wild.getUpperBounds()[0], cw); } if (isImplType(type)) { return type; } if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; Type[] types = pt.getActualTypeArguments(); for (int i = 0; i < types.length; i++) { types[i] = getBoundType(types[i], cw); } Class<?> raw = (Class<?>) getBoundType(pt.getRawType(), cw); return GenericUtils.newGenericType(raw, types); } else if (type instanceof GenericArrayType) { GenericArrayType at = (GenericArrayType) type; return GenericUtils.newArrayType(getBoundType(at.getGenericComponentType(), cw)); } return null; } /** * 解析子类继承父类时所设置的泛型参数(只返回第一个) * @param subclass * @return * @deprecated 不能指定是接口还是类继承,容易出错,用getTypeParameters(Class,Class)代替 */ public static Type getFirstTypeParameters(Class<?> subclass) { Type superclass = subclass.getGenericSuperclass(); if (superclass instanceof Class<?>) { throw new RuntimeException("Missing type parameter."); } return ((ParameterizedType) superclass).getActualTypeArguments()[0]; } /** * 得到继承上级接口、父类所指定的泛型类型 * @param subclass * @param superclass * @return * @deprecated getTypeParameters is a more strong implement. */ public static Class<?>[] getInterfaceTypeParameter(Class<?> subclass,Class<?> superclass) { List<Class<?>> cls=new ArrayList<Class<?>>(); for(Type superClz: subclass.getGenericInterfaces()){ if (superClz instanceof Class<?>) { continue; } ParameterizedType superType=((ParameterizedType) superClz); if(superclass==null || superclass==superType.getRawType()){ for(Type type:superType.getActualTypeArguments()){ if(type instanceof Class){ cls.add((Class<?>) type); }else if(type instanceof GenericArrayType){ Type t=((GenericArrayType) type).getGenericComponentType(); if(t instanceof Class){ cls.add(Array.newInstance((Class<?>)t, 0).getClass()); } } } return cls.toArray(new Class[cls.size()]); } } throw new RuntimeException("the "+subclass.getName()+" doesn't implements " + superclass.getName()); } // 是否确定类型的泛型常量,还是类型不确定的泛型变量。 private static boolean isImplType(Type type) { if (type instanceof Class<?>) return true; if (type instanceof GenericArrayType) { return isImplType(((GenericArrayType) type).getGenericComponentType()); } else if (type instanceof ParameterizedType) { for (Type sub : ((ParameterizedType) type).getActualTypeArguments()) { if (!isImplType(sub)) { return false; } } return true; } else if (type instanceof TypeVariable<?>) { return false; } else if (type instanceof WildcardType) { return false; } throw new IllegalArgumentException(); } /** * 创建一个泛型类型 * @param clz * @param valueType * @return */ public static ParameterizedType newGenericType(Class<?> clz,Type... valueType){ if(!isGenericType(clz)){ throw new IllegalArgumentException(); } return GqGenericResolver.newParameterizedTypeWithOwner(clz.getEnclosingClass(), clz, valueType); } /** * 生成Map的泛型类型 * @param keyType * @param valueType * @return */ public static ParameterizedType newMapType(Type keyType,Type valueType){ if(keyType instanceof Class<?>){ keyType=BeanUtils.toWrapperClass((Class<?>)keyType); } if(valueType instanceof Class<?>){ valueType=BeanUtils.toWrapperClass((Class<?>)valueType); } return GqGenericResolver.newParameterizedTypeWithOwner(null, Map.class, keyType,valueType); } /** * Returns the generic form of {@code supertype}. For example, if this is * {@code ArrayList<String>}, this returns {@code Iterable<String>} given * the input {@code Iterable.class}. * * @param supertype * a superclass of, or interface implemented by, this. */ public static Type getSuperType(Type context, Class<?> contextRawType, Class<?> supertype) { Assert.isTrue(supertype.isAssignableFrom(contextRawType)); return GqGenericResolver.resolve(context, contextRawType, GqGenericResolver.getGenericSupertype(context, contextRawType, supertype)); } /** * 生成List的泛型类型 * @param elementType * @return */ public static ParameterizedType newListType(Type elementType){ if(elementType instanceof Class<?>){ elementType=BeanUtils.toWrapperClass((Class<?>)elementType); } return GqGenericResolver.newParameterizedTypeWithOwner(null, List.class, elementType); } /** * 生成Set的泛型类型 * @param elementType * @return */ public static ParameterizedType newSetType(Type elementType){ if(elementType instanceof Class<?>){ elementType=BeanUtils.toWrapperClass((Class<?>)elementType); } return GqGenericResolver.newParameterizedTypeWithOwner(null, Set.class, elementType); } /** * 生成Array的泛型类型 * @param elementType * @return 注意:作为java中特殊的类型,所有的Array都有对应的class, * 此处产生的是GenericArrayType,如果确认该类型中没有泛型参数(用isRawArray()检测), * 可以使用getRawClass()得到该类型的class形式。 */ public static GenericArrayType newArrayType(Type elementType){ return GqGenericResolver.arrayOf(elementType); } /** * 生成非泛型的数组class * @param elementType * @return */ public static Class<?> newArrayClass(Type componentType){ return Array.newInstance(getRawClass(componentType), 0).getClass(); } /** * 判断指定的类型是否为一个没有泛型的数组类型 * 每个数组都有两种表示方式,基于class的和基于GenericArrayType的。前者可以表示不带泛型参数的类型, * 后者可以表示带有泛型参数的类型。 * 如将后者转换前者 getRawClass(),可能会丢失信息,此方法判断为true的情况下,可以转换为class而不丢失数据类型。 * @param type 要检测的Type * @return * @Throws RuntimeException 输入类型必须是一个泛型Array或class Array,如果输入类型不是一个数组类型,抛出RuntimeException。 */ public static boolean isRawArray(Type type){ if(type instanceof Class<?>){ Class<?> clz=(Class<?>)type; Assert.isTrue(clz.isArray(),"the input type "+ type +" is not a array type!"); return true; } if(type instanceof GenericArrayType){ Type subType=((GenericArrayType)type).getGenericComponentType(); if(isArray(subType)){ return isRawArray(subType); }else{ return subType instanceof Class<?>; } } return false; } /** * 计算Collection的泛型参数 * @param context * @param contextRawType * @return */ public static Type getCollectionType(Type context) { return getCollectionElementType(context, Collection.class); } /** * Returns the element type of this collection type. * * @throws IllegalArgumentException * if this type is not a collection. */ public static Type getCollectionElementType(Type context, Class<?> contextRawType) { Type collectionType = getSuperType(context, contextRawType, Collection.class); return ((ParameterizedType) collectionType).getActualTypeArguments()[0]; } /** * 获取泛型Map的参数类型 * @param mapType * @return */ public static Entry<Type,Type> getMapTypes(Type mapType){ if(mapType instanceof Class){ return new Entry<Type,Type>(Object.class,Object.class); }else{ Type[] types= getMapKeyAndValueTypes(mapType, Map.class); return new Entry<Type,Type>(types[0],types[1]); } } /** * Returns a two element array containing this map's key and value types in * positions 0 and 1 respectively. */ public static Type[] getMapKeyAndValueTypes(Type context, Class<?> contextRawType) { /* * Work around a problem with the declaration of java.util.Properties. * That class should extend Hashtable<String, String>, but it's declared * to extend Hashtable<Object, Object>. */ if (context == Properties.class) { return new Type[] { String.class, String.class }; } Type mapType = getSuperType(context, contextRawType, Map.class); ParameterizedType mapParameterizedType = (ParameterizedType) mapType; return mapParameterizedType.getActualTypeArguments(); } /** * 是否数组类型 * @param field * @return */ public static boolean isArray(Type type){ return GqGenericResolver.isArray(type); } /** * 批量转换为RawClass * @param types * @return */ public static Class<?>[] getRawClasses(Type[] types){ Class<?>[] result=new Class[types.length]; for(int i=0;i<types.length;i++){ result[i]=getRawClass(types[i]); } return result; } /** * 获得数组元素的泛型类型 * @param array * @return */ public static Type getArrayComponentType(Type array) { return GqGenericResolver.getArrayComponentType(array); } /** * 判断指定对象是否定义了泛型 * @param container * @return */ public static boolean isGenericType(GenericDeclaration container){ return container.getTypeParameters().length>0; } }