@Nullable public static Type resolveVariable( TypeVariable variable, final Class classType, boolean resolveInInterfacesOnly) { final Class aClass = getRawType(classType); int index = ArrayUtilRt.find(ReflectionCache.getTypeParameters(aClass), variable); if (index >= 0) { return variable; } final Class[] classes = ReflectionCache.getInterfaces(aClass); final Type[] genericInterfaces = ReflectionCache.getGenericInterfaces(aClass); for (int i = 0; i <= classes.length; i++) { Class anInterface; if (i < classes.length) { anInterface = classes[i]; } else { anInterface = ReflectionCache.getSuperClass(aClass); if (resolveInInterfacesOnly || anInterface == null) { continue; } } final Type resolved = resolveVariable(variable, anInterface); if (resolved instanceof Class || resolved instanceof ParameterizedType) { return resolved; } if (resolved instanceof TypeVariable) { final TypeVariable typeVariable = (TypeVariable) resolved; index = ArrayUtilRt.find(ReflectionCache.getTypeParameters(anInterface), typeVariable); if (index < 0) { LOG.error( "Cannot resolve type variable:\n" + "typeVariable = " + typeVariable + "\n" + "genericDeclaration = " + declarationToString(typeVariable.getGenericDeclaration()) + "\n" + "searching in " + declarationToString(anInterface)); } final Type type = i < genericInterfaces.length ? genericInterfaces[i] : aClass.getGenericSuperclass(); if (type instanceof Class) { return Object.class; } if (type instanceof ParameterizedType) { return getActualTypeArguments((ParameterizedType) type)[index]; } throw new AssertionError("Invalid type: " + type); } } return null; }
public static Type resolveVariableInHierarchy(final TypeVariable variable, final Class aClass) { Type type; Class current = aClass; while ((type = resolveVariable(variable, current, false)) == null) { current = ReflectionCache.getSuperClass(current); if (current == null) { return null; } } if (type instanceof TypeVariable) { return resolveVariableInHierarchy((TypeVariable) type, aClass); } return type; }