为什么要单独拿一篇文章来讲呢?因为里面涉及到的java-Type接口的内容之前没有接触和了解过。我相信在座的很多小伙伴也一定不知道其中的奥秘哦~
你知道Class对象还有一个父接口吗?
以下内容均摘录自 徐郡明 《Mybatis技术内幕》
先简单介绍一下Type接口的基础知识。Type是所有类型的父接口,它有四个子接口和一个实现类,如下图:
下面来看这些子接口和子类所代表的类型
org.apache.ibatis.reflection.TypeParameterResolver
是一个主要用来负责解析字段类型、方法返回值类型和方法参数列表中各个参数的类型的一个工具类。代码如下:
/** * 暴露了三个公用静态方法,分别用于解析Field类型、Method返回类型、方法参数类型 * @author Iwao AVE! */ public class TypeParameterResolver { /** * 解析属性类型 * @return The field type as {@link Type}. If it has type parameters in the * declaration,<br> * they will be resolved to the actual runtime {@link Type}s. */ public static Type resolveFieldType(Field field, Type srcType) { // 属性类型 Type fieldType = field.getGenericType(); // 定义的类 Class<?> declaringClass = field.getDeclaringClass(); // 解析类型 return resolveType(fieldType, srcType, declaringClass); } /** * 解析方法返回值类型 * @return The return type of the method as {@link Type}. If it has type * parameters in the declaration,<br> * they will be resolved to the actual runtime {@link Type}s. */ public static Type resolveReturnType(Method method, Type srcType) { // 返回值类型 Type returnType = method.getGenericReturnType(); // 定义的类 Class<?> declaringClass = method.getDeclaringClass(); // 解析类型 return resolveType(returnType, srcType, declaringClass); } /** * 解析方法参数类型 * @return The parameter types of the method as an array of {@link Type}s. If * they have type parameters in the declaration,<br> * they will be resolved to the actual runtime {@link Type}s. */ public static Type[] resolveParamTypes(Method method, Type srcType) { // 参数类型 Type[] paramTypes = method.getGenericParameterTypes(); // 定义的类 Class<?> declaringClass = method.getDeclaringClass(); Type[] result = new Type[paramTypes.length]; for (int i = 0; i < paramTypes.length; i++) { // 解析类型 result[i] = resolveType(paramTypes[i], srcType, declaringClass); } return result; } /** * 解析类型 * @param type 类型 * @param srcType 来源类型 * @param declaringClass 定义的类 * @return 解析后的类型 */ private static Type resolveType(Type type, Type srcType, Class<?> declaringClass) { if (type instanceof TypeVariable) {// 解析TypeVariable return resolveTypeVar((TypeVariable<?>) type, srcType, declaringClass); } else if (type instanceof ParameterizedType) {// 解析ParameterizedType return resolveParameterizedType((ParameterizedType) type, srcType, declaringClass); } else if (type instanceof GenericArrayType) {// 解析GenericArrayType return resolveGenericArrayType((GenericArrayType) type, srcType, declaringClass); } else { return type;// Class类型直接返回 } } private static Type resolveGenericArrayType(GenericArrayType genericArrayType, Type srcType, Class<?> declaringClass) { Type componentType = genericArrayType.getGenericComponentType(); Type resolvedComponentType = null; if (componentType instanceof TypeVariable) { resolvedComponentType = resolveTypeVar((TypeVariable<?>) componentType, srcType, declaringClass); } else if (componentType instanceof GenericArrayType) { resolvedComponentType = resolveGenericArrayType((GenericArrayType) componentType, srcType, declaringClass); } else if (componentType instanceof ParameterizedType) { resolvedComponentType = resolveParameterizedType((ParameterizedType) componentType, srcType, declaringClass); } if (resolvedComponentType instanceof Class) { return Array.newInstance((Class<?>) resolvedComponentType, 0).getClass(); } else { return new GenericArrayTypeImpl(resolvedComponentType); } } /** * 解析 ParameterizedType 类型 * @param parameterizedType ParameterizedType 类型 * @param srcType 来源类型 * @param declaringClass 定义的类 * @return 解析后的类型 */ private static ParameterizedType resolveParameterizedType(ParameterizedType parameterizedType, Type srcType, Class<?> declaringClass) { Class<?> rawType = (Class<?>) parameterizedType.getRawType(); // 解析 <> 中实际类型 Type[] typeArgs = parameterizedType.getActualTypeArguments(); Type[] args = new Type[typeArgs.length]; for (int i = 0; i < typeArgs.length; i++) { if (typeArgs[i] instanceof TypeVariable) { args[i] = resolveTypeVar((TypeVariable<?>) typeArgs[i], srcType, declaringClass); } else if (typeArgs[i] instanceof ParameterizedType) { args[i] = resolveParameterizedType((ParameterizedType) typeArgs[i], srcType, declaringClass); } else if (typeArgs[i] instanceof WildcardType) { args[i] = resolveWildcardType((WildcardType) typeArgs[i], srcType, declaringClass); } else { args[i] = typeArgs[i]; } } return new ParameterizedTypeImpl(rawType, null, args); } private static Type resolveWildcardType(WildcardType wildcardType, Type srcType, Class<?> declaringClass) { Type[] lowerBounds = resolveWildcardTypeBounds(wildcardType.getLowerBounds(), srcType, declaringClass); Type[] upperBounds = resolveWildcardTypeBounds(wildcardType.getUpperBounds(), srcType, declaringClass); return new WildcardTypeImpl(lowerBounds, upperBounds); } private static Type[] resolveWildcardTypeBounds(Type[] bounds, Type srcType, Class<?> declaringClass) { Type[] result = new Type[bounds.length]; for (int i = 0; i < bounds.length; i++) { if (bounds[i] instanceof TypeVariable) { result[i] = resolveTypeVar((TypeVariable<?>) bounds[i], srcType, declaringClass); } else if (bounds[i] instanceof ParameterizedType) { result[i] = resolveParameterizedType((ParameterizedType) bounds[i], srcType, declaringClass); } else if (bounds[i] instanceof WildcardType) { result[i] = resolveWildcardType((WildcardType) bounds[i], srcType, declaringClass); } else { result[i] = bounds[i]; } } return result; } /** * 解析TypeVariable类型 * @param typeVar * @param srcType * @param declaringClass * @return */ private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass) { Type result = null; Class<?> clazz = null; if (srcType instanceof Class) { clazz = (Class<?>) srcType; } else if (srcType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) srcType; clazz = (Class<?>) parameterizedType.getRawType(); } else { throw new IllegalArgumentException( "The 2nd arg must be Class or ParameterizedType, but was: " + srcType.getClass()); } if (clazz == declaringClass) { Type[] bounds = typeVar.getBounds(); if (bounds.length > 0) { return bounds[0]; } return Object.class; } Type superclass = clazz.getGenericSuperclass(); result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superclass); if (result != null) { return result; } Type[] superInterfaces = clazz.getGenericInterfaces(); for (Type superInterface : superInterfaces) { result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superInterface); if (result != null) { return result; } } return Object.class; } private static Type scanSuperTypes(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass, Class<?> clazz, Type superclass) { if (superclass instanceof ParameterizedType) { ParameterizedType parentAsType = (ParameterizedType) superclass; Class<?> parentAsClass = (Class<?>) parentAsType.getRawType(); TypeVariable<?>[] parentTypeVars = parentAsClass.getTypeParameters(); if (srcType instanceof ParameterizedType) { parentAsType = translateParentTypeVars((ParameterizedType) srcType, clazz, parentAsType); } if (declaringClass == parentAsClass) { for (int i = 0; i < parentTypeVars.length; i++) { if (typeVar == parentTypeVars[i]) { return parentAsType.getActualTypeArguments()[i]; } } } if (declaringClass.isAssignableFrom(parentAsClass)) { return resolveTypeVar(typeVar, parentAsType, declaringClass); } } else if (superclass instanceof Class && declaringClass.isAssignableFrom((Class<?>) superclass)) { return resolveTypeVar(typeVar, superclass, declaringClass); } return null; } private static ParameterizedType translateParentTypeVars(ParameterizedType srcType, Class<?> srcClass, ParameterizedType parentType) { Type[] parentTypeArgs = parentType.getActualTypeArguments(); Type[] srcTypeArgs = srcType.getActualTypeArguments(); TypeVariable<?>[] srcTypeVars = srcClass.getTypeParameters(); Type[] newParentArgs = new Type[parentTypeArgs.length]; boolean noChange = true; for (int i = 0; i < parentTypeArgs.length; i++) { if (parentTypeArgs[i] instanceof TypeVariable) { for (int j = 0; j < srcTypeVars.length; j++) { if (srcTypeVars[j] == parentTypeArgs[i]) { noChange = false; newParentArgs[i] = srcTypeArgs[j]; } } } else { newParentArgs[i] = parentTypeArgs[i]; } } return noChange ? parentType : new ParameterizedTypeImpl((Class<?>) parentType.getRawType(), null, newParentArgs); } private TypeParameterResolver() { super(); } static class ParameterizedTypeImpl implements ParameterizedType { private Class<?> rawType; private Type ownerType; private Type[] actualTypeArguments; public ParameterizedTypeImpl(Class<?> rawType, Type ownerType, Type[] actualTypeArguments) { super(); this.rawType = rawType; this.ownerType = ownerType; this.actualTypeArguments = actualTypeArguments; } @Override public Type[] getActualTypeArguments() { return actualTypeArguments; } @Override public Type getOwnerType() { return ownerType; } @Override public Type getRawType() { return rawType; } @Override public String toString() { return "ParameterizedTypeImpl [rawType=" + rawType + ", ownerType=" + ownerType + ", actualTypeArguments=" + Arrays.toString(actualTypeArguments) + "]"; } } static class WildcardTypeImpl implements WildcardType { private Type[] lowerBounds; private Type[] upperBounds; WildcardTypeImpl(Type[] lowerBounds, Type[] upperBounds) { super(); this.lowerBounds = lowerBounds; this.upperBounds = upperBounds; } @Override public Type[] getLowerBounds() { return lowerBounds; } @Override public Type[] getUpperBounds() { return upperBounds; } } static class GenericArrayTypeImpl implements GenericArrayType { private Type genericComponentType; GenericArrayTypeImpl(Type genericComponentType) { super(); this.genericComponentType = genericComponentType; } @Override public Type getGenericComponentType() { return genericComponentType; } } } 复制代码