Java Code Examples for java.lang.reflect.TypeVariable#equals()

The following examples show how to use java.lang.reflect.TypeVariable#equals() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Types.java    From keycloak with Apache License 2.0 6 votes vote down vote up
/**
 * Finds an actual value of a type variable. The method looks in a class hierarchy for a class defining the variable
 * and returns the value if present.
 *
 * @param root
 * @param typeVariable
 * @return actual type of the type variable
 */
public static Type resolveTypeVariable(Class<?> root, TypeVariable<?> typeVariable)
{
    if (typeVariable.getGenericDeclaration() instanceof Class<?>)
    {
        Class<?> classDeclaringTypeVariable = (Class<?>) typeVariable.getGenericDeclaration();
        Type[] types = findParameterizedTypes(root, classDeclaringTypeVariable);
        if (types == null) return  null;
        for (int i = 0; i < types.length; i++)
        {
            TypeVariable<?> tv = classDeclaringTypeVariable.getTypeParameters()[i];
            if (tv.equals(typeVariable))
            {
                return types[i];
            }
        }
    }
    return null;
}
 
Example 2
Source File: ClassUtil.java    From qaf with MIT License 6 votes vote down vote up
private static Type getTypeVariableViaGenericInterface(Class<?> clazz, Class<?> classDeclaringTypevariable,
		TypeVariable<?> typevariable) {
	for (Type genericInterface : clazz.getGenericInterfaces()) {

		if (genericInterface instanceof ParameterizedType) {
			ParameterizedType parameterizedType = (ParameterizedType) genericInterface;

			for (int i = 0; i < classDeclaringTypevariable.getTypeParameters().length; i++) {
				TypeVariable<?> tv = classDeclaringTypevariable.getTypeParameters()[i];
				if (tv.equals(typevariable)) {
					return parameterizedType.getActualTypeArguments()[i];
				}
			}
		} else if (genericInterface instanceof Class) {
			return getTypeVariableViaGenericInterface((Class<?>) genericInterface, classDeclaringTypevariable,
					typevariable);
		}
	}
	return null;
}
 
Example 3
Source File: Lang_15_TypeUtils_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * <p> Checks if the subject type may be implicitly cast to the target type
 * variable following the Java generics rules. </p>
 *
 * @param type the subject type to be assigned to the target type
 * @param toTypeVariable the target type variable
 * @param typeVarAssigns a map with type variables
 * @return true if <code>type</code> is assignable to
 * <code>toTypeVariable</code>.
 */
private static boolean isAssignable(Type type, TypeVariable<?> toTypeVariable,
        Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
        return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toTypeVariable == null) {
        return false;
    }

    // all types are assignable to themselves
    if (toTypeVariable.equals(type)) {
        return true;
    }

    if (type instanceof TypeVariable<?>) {
        // a type variable is assignable to another type variable, if
        // and only if the former is the latter, extends the latter, or
        // is otherwise a descendant of the latter.
        Type[] bounds = getImplicitBounds((TypeVariable<?>) type);

        for (Type bound : bounds) {
            if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
                return true;
            }
        }
    }

    if (type instanceof Class<?> || type instanceof ParameterizedType
            || type instanceof GenericArrayType || type instanceof WildcardType) {
        return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
}
 
Example 4
Source File: GenericTypeHelper.java    From bazel with Apache License 2.0 5 votes vote down vote up
/**
 * If type is a parameterized type, searches the given type variable in the list
 * of declared type variables, and then returns the corresponding actual type.
 * Returns null if the type variable is not defined by type.
 */
private static Type matchTypeVariable(Type type, TypeVariable<?> variable) {
  if (type instanceof ParameterizedType) {
    Class<?> rawInterfaceType = getRawType(type);
    TypeVariable<?>[] typeParameters = rawInterfaceType.getTypeParameters();
    for (int i = 0; i < typeParameters.length; i++) {
      if (variable.equals(typeParameters[i])) {
        return ((ParameterizedType) type).getActualTypeArguments()[i];
      }
    }
  }
  return null;
}
 
Example 5
Source File: TypeUtils.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p> Checks if the subject type may be implicitly cast to the target type
 * variable following the Java generics rules. </p>
 *
 * @param type the subject type to be assigned to the target type
 * @param toTypeVariable the target type variable
 * @param typeVarAssigns a map with type variables
 * @return true if <code>type</code> is assignable to
 * <code>toTypeVariable</code>.
 */
private static boolean isAssignable(Type type, TypeVariable<?> toTypeVariable,
        Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
        return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toTypeVariable == null) {
        return false;
    }

    // all types are assignable to themselves
    if (toTypeVariable.equals(type)) {
        return true;
    }

    if (type instanceof TypeVariable<?>) {
        // a type variable is assignable to another type variable, if
        // and only if the former is the latter, extends the latter, or
        // is otherwise a descendant of the latter.
        Type[] bounds = getImplicitBounds((TypeVariable<?>) type);

        for (Type bound : bounds) {
            if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
                return true;
            }
        }
    }

    if (type instanceof Class<?> || type instanceof ParameterizedType
            || type instanceof GenericArrayType || type instanceof WildcardType) {
        return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
}
 
Example 6
Source File: TypeUtils.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p> Checks if the subject type may be implicitly cast to the target type
 * variable following the Java generics rules. </p>
 *
 * @param type the subject type to be assigned to the target type
 * @param toTypeVariable the target type variable
 * @param typeVarAssigns a map with type variables
 * @return true if <code>type</code> is assignable to
 * <code>toTypeVariable</code>.
 */
private static boolean isAssignable(final Type type, final TypeVariable<?> toTypeVariable,
        final Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
        return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toTypeVariable == null) {
        return false;
    }

    // all types are assignable to themselves
    if (toTypeVariable.equals(type)) {
        return true;
    }

    if (type instanceof TypeVariable<?>) {
        // a type variable is assignable to another type variable, if
        // and only if the former is the latter, extends the latter, or
        // is otherwise a descendant of the latter.
        final Type[] bounds = getImplicitBounds((TypeVariable<?>) type);

        for (final Type bound : bounds) {
            if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
                return true;
            }
        }
    }

    if (type instanceof Class<?> || type instanceof ParameterizedType
            || type instanceof GenericArrayType || type instanceof WildcardType) {
        return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
}
 
Example 7
Source File: TypeUtils.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p> Checks if the subject type may be implicitly cast to the target type
 * variable following the Java generics rules. </p>
 *
 * @param type the subject type to be assigned to the target type
 * @param toTypeVariable the target type variable
 * @param typeVarAssigns a map with type variables
 * @return true if <code>type</code> is assignable to
 * <code>toTypeVariable</code>.
 */
private static boolean isAssignable(Type type, TypeVariable<?> toTypeVariable,
        Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
        return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toTypeVariable == null) {
        return false;
    }

    // all types are assignable to themselves
    if (toTypeVariable.equals(type)) {
        return true;
    }

    if (type instanceof TypeVariable<?>) {
        // a type variable is assignable to another type variable, if
        // and only if the former is the latter, extends the latter, or
        // is otherwise a descendant of the latter.
        Type[] bounds = getImplicitBounds((TypeVariable<?>) type);

        for (Type bound : bounds) {
            if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
                return true;
            }
        }
    }

    if (type instanceof Class<?> || type instanceof ParameterizedType
            || type instanceof GenericArrayType || type instanceof WildcardType) {
        return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
}
 
Example 8
Source File: TypeUtils.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * <p> Checks if the subject type may be implicitly cast to the target type
 * variable following the Java generics rules. </p>
 *
 * @param type the subject type to be assigned to the target type
 * @param toTypeVariable the target type variable
 * @return true if <code>type</code> is assignable to
 * <code>toTypeVariable</code>.
 */
private static boolean isAssignable(Type type, TypeVariable<?> toTypeVariable,
        Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
        return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toTypeVariable == null) {
        return false;
    }

    // all types are assignable to themselves
    if (toTypeVariable.equals(type)) {
        return true;
    }

    if (type instanceof TypeVariable<?>) {
        // a type variable is assignable to another type variable, if
        // and only if the former is the latter, extends the latter, or
        // is otherwise a descendant of the latter.
        Type[] bounds = getImplicitBounds((TypeVariable<?>) type);

        for (Type bound : bounds) {
            if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
                return true;
            }
        }
    }

    if (type instanceof Class<?> || type instanceof ParameterizedType
            || type instanceof GenericArrayType || type instanceof WildcardType) {
        return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
}
 
Example 9
Source File: Types.java    From google-http-java-client with Apache License 2.0 5 votes vote down vote up
/**
 * Resolves the actual type of the given type variable that comes from a field type based on the
 * given context list.
 *
 * <p>In case the type variable can be resolved partially, it will return the partially resolved
 * type variable.
 *
 * @param context context list, ordering from least specific to most specific type context, for
 *     example container class and then its field
 * @param typeVariable type variable
 * @return resolved or partially resolved actual type (type variable, class, parameterized type,
 *     or generic array type, but not wildcard type) or {@code null} if unable to resolve at all
 */
public static Type resolveTypeVariable(List<Type> context, TypeVariable<?> typeVariable) {
  // determine where the type variable was declared
  GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
  if (genericDeclaration instanceof Class<?>) {
    Class<?> rawGenericDeclaration = (Class<?>) genericDeclaration;
    // check if the context extends that declaration
    int contextIndex = context.size();
    ParameterizedType parameterizedType = null;
    while (parameterizedType == null && --contextIndex >= 0) {
      parameterizedType =
          getSuperParameterizedType(context.get(contextIndex), rawGenericDeclaration);
    }
    if (parameterizedType != null) {
      // find the type variable's index in the declaration's type parameters
      TypeVariable<?>[] typeParameters = genericDeclaration.getTypeParameters();
      int index = 0;
      for (; index < typeParameters.length; index++) {
        TypeVariable<?> typeParameter = typeParameters[index];
        if (typeParameter.equals(typeVariable)) {
          break;
        }
      }
      // use that index to get the actual type argument
      Type result = parameterizedType.getActualTypeArguments()[index];
      if (result instanceof TypeVariable<?>) {
        // attempt to resolve type variable
        Type resolve = resolveTypeVariable(context, (TypeVariable<?>) result);
        if (resolve != null) {
          return resolve;
        }
        // partially resolved type variable is okay
      }
      return result;
    }
  }
  return null;
}
 
Example 10
Source File: TypeUtils.java    From dolphin-platform with Apache License 2.0 5 votes vote down vote up
/**
 * <p>Checks if the subject type may be implicitly cast to the target type
 * variable following the Java generics rules.</p>
 *
 * @param type           the subject type to be assigned to the target type
 * @param toTypeVariable the target type variable
 * @param typeVarAssigns a map with type variables
 * @return {@code true} if {@code type} is assignable to
 * {@code toTypeVariable}.
 */
private static boolean isAssignable(final Type type, final TypeVariable<?> toTypeVariable,
                                    final Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
        return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toTypeVariable == null) {
        return false;
    }

    // all types are assignable to themselves
    if (toTypeVariable.equals(type)) {
        return true;
    }

    if (type instanceof TypeVariable<?>) {
        // a type variable is assignable to another type variable, if
        // and only if the former is the latter, extends the latter, or
        // is otherwise a descendant of the latter.
        final Type[] bounds = getImplicitBounds((TypeVariable<?>) type);

        for (final Type bound : bounds) {
            if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
                return true;
            }
        }
    }

    if (type instanceof Class<?> || type instanceof ParameterizedType
            || type instanceof GenericArrayType || type instanceof WildcardType) {
        return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
}
 
Example 11
Source File: Parameters.java    From opt4j with MIT License 5 votes vote down vote up
protected static Type getType(Class<?> clazz, String variable, Map<Type, ParameterizedType> map) {

		// get first
		ParameterizedType ptype = map.get(clazz);
		if (ptype == null) {
			return null;
		}

		Type type = null;
		for (int j = 0; j < ptype.getActualTypeArguments().length; j++) {
			TypeVariable<?> v = clazz.getTypeParameters()[j];
			if (v.getName().equals(variable)) {
				type = ptype.getActualTypeArguments()[j];
			}
		}

		while (type instanceof TypeVariable<?>) {
			TypeVariable<?> var = (TypeVariable<?>) type;
			ParameterizedType paramType = map.get(var.getGenericDeclaration());
			Class<?> freeType = (Class<?>) paramType.getRawType();

			int size = freeType.getTypeParameters().length;

			for (int j = 0; j < size; j++) {
				TypeVariable<?> f = freeType.getTypeParameters()[j];
				if (f.equals(var)) {
					type = paramType.getActualTypeArguments()[j];
					break;
				}
			}
		}

		return type;
	}
 
Example 12
Source File: Lang_15_TypeUtils_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * <p> Checks if the subject type may be implicitly cast to the target type
 * variable following the Java generics rules. </p>
 *
 * @param type the subject type to be assigned to the target type
 * @param toTypeVariable the target type variable
 * @param typeVarAssigns a map with type variables
 * @return true if <code>type</code> is assignable to
 * <code>toTypeVariable</code>.
 */
private static boolean isAssignable(Type type, TypeVariable<?> toTypeVariable,
        Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
        return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toTypeVariable == null) {
        return false;
    }

    // all types are assignable to themselves
    if (toTypeVariable.equals(type)) {
        return true;
    }

    if (type instanceof TypeVariable<?>) {
        // a type variable is assignable to another type variable, if
        // and only if the former is the latter, extends the latter, or
        // is otherwise a descendant of the latter.
        Type[] bounds = getImplicitBounds((TypeVariable<?>) type);

        for (Type bound : bounds) {
            if (isAssignable(bound, toTypeVariable, typeVarAssigns)) {
                return true;
            }
        }
    }

    if (type instanceof Class<?> || type instanceof ParameterizedType
            || type instanceof GenericArrayType || type instanceof WildcardType) {
        return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
}
 
Example 13
Source File: ClassUtil.java    From qaf with MIT License 5 votes vote down vote up
/**
 * Finds an actual value of a type variable. The method looks in a class
 * hierarchy for a class defining the variable and returns the value if present.
 * 
 * @param clazz
 * @param typevariable
 * @return actual type of the type variable
 */
public static Type getActualValueOfTypevariable(Class<?> clazz, TypeVariable<?> typevariable) {
	if (typevariable.getGenericDeclaration() instanceof Class<?>) {
		Class<?> classDeclaringTypevariable = (Class<?>) typevariable.getGenericDeclaration();

		// find the generic version of classDeclaringTypevariable

		Type fromInterface = getTypeVariableViaGenericInterface(clazz, classDeclaringTypevariable, typevariable);
		if (fromInterface != null) {
			return fromInterface;
		}

		while (clazz.getSuperclass() != null) {
			if (clazz.getSuperclass().equals(classDeclaringTypevariable)) {
				// found it
				ParameterizedType parameterizedSuperclass = (ParameterizedType) clazz.getGenericSuperclass();

				for (int i = 0; i < classDeclaringTypevariable.getTypeParameters().length; i++) {
					TypeVariable<?> tv = classDeclaringTypevariable.getTypeParameters()[i];
					if (tv.equals(typevariable)) {
						return parameterizedSuperclass.getActualTypeArguments()[i];
					}
				}
			}

			clazz = clazz.getSuperclass();
		}
	}

	throw new RuntimeException("Unable to determine value of type parameter " + typevariable);
}
 
Example 14
Source File: CovariantTypes.java    From quarkus with Apache License 2.0 5 votes vote down vote up
/**
 * Returns <tt>true</tt> if <tt>type2</tt> is a "sub-variable" of <tt>type1</tt>, i.e. if they are equal or if
 * <tt>type2</tt> (transitively) extends <tt>type1</tt>.
 */
private static boolean isAssignableFrom(TypeVariable<?> type1, TypeVariable<?> type2) {
    if (type1.equals(type2)) {
        return true;
    }
    // if a type variable extends another type variable, it cannot declare other bounds
    if (type2.getBounds()[0] instanceof TypeVariable<?>) {
        return isAssignableFrom(type1, (TypeVariable<?>) type2.getBounds()[0]);
    }
    return false;
}
 
Example 15
Source File: GenericTypeResolver.java    From spring4-understanding with Apache License 2.0 4 votes vote down vote up
/**
 * Determine the target type for the generic return type of the given
 * <em>generic method</em>, where formal type variables are declared on
 * the given method itself.
 * <p>For example, given a factory method with the following signature,
 * if {@code resolveReturnTypeForGenericMethod()} is invoked with the reflected
 * method for {@code creatProxy()} and an {@code Object[]} array containing
 * {@code MyService.class}, {@code resolveReturnTypeForGenericMethod()} will
 * infer that the target return type is {@code MyService}.
 * <pre class="code">{@code public static <T> T createProxy(Class<T> clazz)}</pre>
 * <h4>Possible Return Values</h4>
 * <ul>
 * <li>the target return type, if it can be inferred</li>
 * <li>the {@linkplain Method#getReturnType() standard return type}, if
 * the given {@code method} does not declare any {@linkplain
 * Method#getTypeParameters() formal type variables}</li>
 * <li>the {@linkplain Method#getReturnType() standard return type}, if the
 * target return type cannot be inferred (e.g., due to type erasure)</li>
 * <li>{@code null}, if the length of the given arguments array is shorter
 * than the length of the {@linkplain
 * Method#getGenericParameterTypes() formal argument list} for the given
 * method</li>
 * </ul>
 * @param method the method to introspect, never {@code null}
 * @param args the arguments that will be supplied to the method when it is
 * invoked (never {@code null})
 * @param classLoader the ClassLoader to resolve class names against, if necessary
 * (may be {@code null})
 * @return the resolved target return type, the standard return type, or {@code null}
 * @since 3.2.5
 * @see #resolveReturnType
 */
public static Class<?> resolveReturnTypeForGenericMethod(Method method, Object[] args, ClassLoader classLoader) {
	Assert.notNull(method, "Method must not be null");
	Assert.notNull(args, "Argument array must not be null");

	TypeVariable<Method>[] declaredTypeVariables = method.getTypeParameters();
	Type genericReturnType = method.getGenericReturnType();
	Type[] methodArgumentTypes = method.getGenericParameterTypes();

	// No declared type variables to inspect, so just return the standard return type.
	if (declaredTypeVariables.length == 0) {
		return method.getReturnType();
	}

	// The supplied argument list is too short for the method's signature, so
	// return null, since such a method invocation would fail.
	if (args.length < methodArgumentTypes.length) {
		return null;
	}

	// Ensure that the type variable (e.g., T) is declared directly on the method
	// itself (e.g., via <T>), not on the enclosing class or interface.
	boolean locallyDeclaredTypeVariableMatchesReturnType = false;
	for (TypeVariable<Method> currentTypeVariable : declaredTypeVariables) {
		if (currentTypeVariable.equals(genericReturnType)) {
			locallyDeclaredTypeVariableMatchesReturnType = true;
			break;
		}
	}

	if (locallyDeclaredTypeVariableMatchesReturnType) {
		for (int i = 0; i < methodArgumentTypes.length; i++) {
			Type currentMethodArgumentType = methodArgumentTypes[i];
			if (currentMethodArgumentType.equals(genericReturnType)) {
				return args[i].getClass();
			}
			if (currentMethodArgumentType instanceof ParameterizedType) {
				ParameterizedType parameterizedType = (ParameterizedType) currentMethodArgumentType;
				Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
				for (Type typeArg : actualTypeArguments) {
					if (typeArg.equals(genericReturnType)) {
						Object arg = args[i];
						if (arg instanceof Class) {
							return (Class<?>) arg;
						}
						else if (arg instanceof String && classLoader != null) {
							try {
								return classLoader.loadClass((String) arg);
							}
							catch (ClassNotFoundException ex) {
								throw new IllegalStateException(
										"Could not resolve specific class name argument [" + arg + "]", ex);
							}
						}
						else {
							// Consider adding logic to determine the class of the typeArg, if possible.
							// For now, just fall back...
							return method.getReturnType();
						}
					}
				}
			}
		}
	}

	// Fall back...
	return method.getReturnType();
}
 
Example 16
Source File: FieldInfo.java    From uavstack with Apache License 2.0 4 votes vote down vote up
private static Type getInheritGenericType(Class<?> clazz, Type type, TypeVariable<?> tv) {
    GenericDeclaration gd = tv.getGenericDeclaration();

    Class<?> class_gd = null;
    if (gd instanceof Class) {
        class_gd = (Class<?>) tv.getGenericDeclaration();
    }

    Type[] arguments = null;
    if (class_gd == clazz) {
        if (type instanceof ParameterizedType) {
            ParameterizedType ptype = (ParameterizedType) type;
            arguments = ptype.getActualTypeArguments();
        }
    } else {
        for (Class<?> c = clazz; c != null && c != Object.class && c != class_gd; c = c.getSuperclass()) {
            Type superType = c.getGenericSuperclass();

            if (superType instanceof ParameterizedType) {
                ParameterizedType p_superType = (ParameterizedType) superType;
                Type[] p_superType_args = p_superType.getActualTypeArguments();
                getArgument(p_superType_args, c.getTypeParameters(), arguments);
                arguments = p_superType_args;
            }
        }
    }

    if (arguments == null || class_gd == null) {
        return null;
    }

    Type actualType = null;
    TypeVariable<?>[] typeVariables = class_gd.getTypeParameters();
    for (int j = 0; j < typeVariables.length; ++j) {
        if (tv.equals(typeVariables[j])) {
            actualType = arguments[j];
            break;
        }
    }

    return actualType;
}
 
Example 17
Source File: GenericTypeResolver.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Determine the target type for the generic return type of the given
 * <em>generic method</em>, where formal type variables are declared on
 * the given method itself.
 * <p>For example, given a factory method with the following signature,
 * if {@code resolveReturnTypeForGenericMethod()} is invoked with the reflected
 * method for {@code creatProxy()} and an {@code Object[]} array containing
 * {@code MyService.class}, {@code resolveReturnTypeForGenericMethod()} will
 * infer that the target return type is {@code MyService}.
 * <pre class="code">{@code public static <T> T createProxy(Class<T> clazz)}</pre>
 * <h4>Possible Return Values</h4>
 * <ul>
 * <li>the target return type, if it can be inferred</li>
 * <li>the {@linkplain Method#getReturnType() standard return type}, if
 * the given {@code method} does not declare any {@linkplain
 * Method#getTypeParameters() formal type variables}</li>
 * <li>the {@linkplain Method#getReturnType() standard return type}, if the
 * target return type cannot be inferred (e.g., due to type erasure)</li>
 * <li>{@code null}, if the length of the given arguments array is shorter
 * than the length of the {@linkplain
 * Method#getGenericParameterTypes() formal argument list} for the given
 * method</li>
 * </ul>
 * @param method the method to introspect, never {@code null}
 * @param args the arguments that will be supplied to the method when it is
 * invoked (never {@code null})
 * @param classLoader the ClassLoader to resolve class names against, if necessary
 * (may be {@code null})
 * @return the resolved target return type, the standard return type, or {@code null}
 * @since 3.2.5
 * @deprecated as of Spring Framework 4.3.8, superseded by {@link ResolvableType} usage
 */
@Deprecated
public static Class<?> resolveReturnTypeForGenericMethod(Method method, Object[] args, ClassLoader classLoader) {
	Assert.notNull(method, "Method must not be null");
	Assert.notNull(args, "Argument array must not be null");

	TypeVariable<Method>[] declaredTypeVariables = method.getTypeParameters();
	Type genericReturnType = method.getGenericReturnType();
	Type[] methodArgumentTypes = method.getGenericParameterTypes();

	// No declared type variables to inspect, so just return the standard return type.
	if (declaredTypeVariables.length == 0) {
		return method.getReturnType();
	}

	// The supplied argument list is too short for the method's signature, so
	// return null, since such a method invocation would fail.
	if (args.length < methodArgumentTypes.length) {
		return null;
	}

	// Ensure that the type variable (e.g., T) is declared directly on the method
	// itself (e.g., via <T>), not on the enclosing class or interface.
	boolean locallyDeclaredTypeVariableMatchesReturnType = false;
	for (TypeVariable<Method> currentTypeVariable : declaredTypeVariables) {
		if (currentTypeVariable.equals(genericReturnType)) {
			locallyDeclaredTypeVariableMatchesReturnType = true;
			break;
		}
	}

	if (locallyDeclaredTypeVariableMatchesReturnType) {
		for (int i = 0; i < methodArgumentTypes.length; i++) {
			Type currentMethodArgumentType = methodArgumentTypes[i];
			if (currentMethodArgumentType.equals(genericReturnType)) {
				return args[i].getClass();
			}
			if (currentMethodArgumentType instanceof ParameterizedType) {
				ParameterizedType parameterizedType = (ParameterizedType) currentMethodArgumentType;
				Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
				for (Type typeArg : actualTypeArguments) {
					if (typeArg.equals(genericReturnType)) {
						Object arg = args[i];
						if (arg instanceof Class) {
							return (Class<?>) arg;
						}
						else if (arg instanceof String && classLoader != null) {
							try {
								return classLoader.loadClass((String) arg);
							}
							catch (ClassNotFoundException ex) {
								throw new IllegalStateException(
										"Could not resolve specific class name argument [" + arg + "]", ex);
							}
						}
						else {
							// Consider adding logic to determine the class of the typeArg, if possible.
							// For now, just fall back...
							return method.getReturnType();
						}
					}
				}
			}
		}
	}

	// Fall back...
	return method.getReturnType();
}
 
Example 18
Source File: InvariantTypes.java    From quarkus with Apache License 2.0 4 votes vote down vote up
private static boolean isAssignableFrom(TypeVariable<?> type1, TypeVariable<?> type2) {
    return type1.equals(type2);
}