Search in sources :

Example 71 with TypeVariable

use of java.lang.reflect.TypeVariable in project spock by spockframework.

the class GenericTypeReflector method capture.

/**
	 * Applies capture conversion to the given type.
	 */
public static Type capture(Type type) {
    VarMap varMap = new VarMap();
    List<CaptureTypeImpl> toInit = new ArrayList<CaptureTypeImpl>();
    if (type instanceof ParameterizedType) {
        ParameterizedType pType = (ParameterizedType) type;
        Class<?> clazz = (Class<?>) pType.getRawType();
        Type[] arguments = pType.getActualTypeArguments();
        TypeVariable<?>[] vars = clazz.getTypeParameters();
        Type[] capturedArguments = new Type[arguments.length];
        assert arguments.length == vars.length;
        for (int i = 0; i < arguments.length; i++) {
            Type argument = arguments[i];
            if (argument instanceof WildcardType) {
                CaptureTypeImpl captured = new CaptureTypeImpl((WildcardType) argument, vars[i]);
                argument = captured;
                toInit.add(captured);
            }
            capturedArguments[i] = argument;
            varMap.add(vars[i], argument);
        }
        for (CaptureTypeImpl captured : toInit) {
            captured.init(varMap);
        }
        Type ownerType = (pType.getOwnerType() == null) ? null : capture(pType.getOwnerType());
        return new ParameterizedTypeImpl(clazz, capturedArguments, ownerType);
    } else {
        return type;
    }
}
Also used : ArrayList(java.util.ArrayList) ParameterizedType(java.lang.reflect.ParameterizedType) GenericArrayType(java.lang.reflect.GenericArrayType) WildcardType(java.lang.reflect.WildcardType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) WildcardType(java.lang.reflect.WildcardType) TypeVariable(java.lang.reflect.TypeVariable)

Example 72 with TypeVariable

use of java.lang.reflect.TypeVariable in project spring-framework by spring-projects.

the class AutowireUtils method resolveReturnTypeForFactoryMethod.

/**
	 * Determine the target type for the generic return type of the given
	 * <em>generic factory 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 resolveReturnTypeForFactoryMethod()} is invoked with the reflected
	 * method for {@code creatProxy()} and an {@code Object[]} array containing
	 * {@code MyService.class}, {@code resolveReturnTypeForFactoryMethod()} 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 (never {@code null})
	 * @return the resolved target return type or the standard method return type
	 * @since 3.2.5
	 */
public static Class<?> resolveReturnTypeForFactoryMethod(Method method, Object[] args, ClassLoader classLoader) {
    Assert.notNull(method, "Method must not be null");
    Assert.notNull(args, "Argument array must not be null");
    Assert.notNull(classLoader, "ClassLoader must not be null");
    TypeVariable<Method>[] declaredTypeVariables = method.getTypeParameters();
    Type genericReturnType = method.getGenericReturnType();
    Type[] methodParameterTypes = method.getGenericParameterTypes();
    Assert.isTrue(args.length == methodParameterTypes.length, "Argument array does not match parameter count");
    // 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 < methodParameterTypes.length; i++) {
            Type methodParameterType = methodParameterTypes[i];
            Object arg = args[i];
            if (methodParameterType.equals(genericReturnType)) {
                if (arg instanceof TypedStringValue) {
                    TypedStringValue typedValue = ((TypedStringValue) arg);
                    if (typedValue.hasTargetType()) {
                        return typedValue.getTargetType();
                    }
                    try {
                        return typedValue.resolveTargetType(classLoader);
                    } catch (ClassNotFoundException ex) {
                        throw new IllegalStateException("Failed to resolve value type [" + typedValue.getTargetTypeName() + "] for factory method argument", ex);
                    }
                }
                // Only consider argument type if it is a simple value...
                if (arg != null && !(arg instanceof BeanMetadataElement)) {
                    return arg.getClass();
                }
                return method.getReturnType();
            } else if (methodParameterType instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) methodParameterType;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                for (Type typeArg : actualTypeArguments) {
                    if (typeArg.equals(genericReturnType)) {
                        if (arg instanceof Class) {
                            return (Class<?>) arg;
                        } else {
                            String className = null;
                            if (arg instanceof String) {
                                className = (String) arg;
                            } else if (arg instanceof TypedStringValue) {
                                TypedStringValue typedValue = ((TypedStringValue) arg);
                                String targetTypeName = typedValue.getTargetTypeName();
                                if (targetTypeName == null || Class.class.getName().equals(targetTypeName)) {
                                    className = typedValue.getValue();
                                }
                            }
                            if (className != null) {
                                try {
                                    return ClassUtils.forName(className, classLoader);
                                } catch (ClassNotFoundException ex) {
                                    throw new IllegalStateException("Could not resolve class name [" + arg + "] for factory method argument", ex);
                                }
                            }
                            // For now, just fall back...
                            return method.getReturnType();
                        }
                    }
                }
            }
        }
    }
    // Fall back...
    return method.getReturnType();
}
Also used : Method(java.lang.reflect.Method) BeanMetadataElement(org.springframework.beans.BeanMetadataElement) ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) TypeVariable(java.lang.reflect.TypeVariable) TypedStringValue(org.springframework.beans.factory.config.TypedStringValue)

Example 73 with TypeVariable

use of java.lang.reflect.TypeVariable in project robovm by robovm.

the class OldGenericReflectionCornerCases method testMultipleBoundedWildcardUnEquality.

@SuppressWarnings("unchecked")
public void testMultipleBoundedWildcardUnEquality() throws Exception {
    Class<? extends MultipleBoundedWildcardUnEquality> clazz = MultipleBoundedWildcardUnEquality.class;
    // new WildcardEquality<Object>().wildcardEquality(new Pair<String,
    // Integer>());
    Method method = clazz.getDeclaredMethod("multipleBoundedWildcardUnEquality", Pair.class);
    TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
    assertLenghtOne(typeParameters);
    TypeVariable<?> typeParameter = typeParameters[0];
    Type[] typeParameterBounds = typeParameter.getBounds();
    assertEquals(2, typeParameterBounds.length);
    assertEquals(Object.class, typeParameterBounds[0]);
    assertInstanceOf(ParameterizedType.class, typeParameterBounds[1]);
    ParameterizedType parameterizedType = (ParameterizedType) typeParameterBounds[1];
    assertEquals(Comparable.class, parameterizedType.getRawType());
    Type[] typeArguments = parameterizedType.getActualTypeArguments();
    assertLenghtOne(typeArguments);
    assertInstanceOf(ParameterizedType.class, typeArguments[0]);
    ParameterizedType type = (ParameterizedType) typeArguments[0];
    assertEquals(typeParameter, type.getActualTypeArguments()[0]);
    assertEquals(MultipleBoundedWildcardUnEquality.class, type.getRawType());
    Type[] parameterTypes = method.getGenericParameterTypes();
    assertLenghtOne(parameterTypes);
    Type parameter = parameterTypes[0];
    assertInstanceOf(ParameterizedType.class, parameter);
    ParameterizedType paramType = (ParameterizedType) parameter;
    Type[] actualTypeArguments = paramType.getActualTypeArguments();
    assertEquals(2, actualTypeArguments.length);
    Type firstArgument = actualTypeArguments[0];
    assertInstanceOf(WildcardType.class, firstArgument);
    WildcardType firstWildcardArgument = (WildcardType) firstArgument;
    Type secondArgument = actualTypeArguments[1];
    assertInstanceOf(WildcardType.class, secondArgument);
    WildcardType secondWildcardArgument = (WildcardType) secondArgument;
    assertNotEquals(firstWildcardArgument, secondWildcardArgument);
    Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
    assertLenghtOne(firstWildcardArgumentUpperBounds);
    Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
    Type[] secondWildcardArgumentLowerBounds = secondWildcardArgument.getLowerBounds();
    assertLenghtOne(secondWildcardArgumentLowerBounds);
    Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentLowerBounds[0];
    assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) WildcardType(java.lang.reflect.WildcardType) WildcardType(java.lang.reflect.WildcardType) TypeVariable(java.lang.reflect.TypeVariable) Method(java.lang.reflect.Method)

Example 74 with TypeVariable

use of java.lang.reflect.TypeVariable in project robovm by robovm.

the class OldGenericReflectionCornerCases method testMultipleBoundedWildcard.

@SuppressWarnings("unchecked")
public void testMultipleBoundedWildcard() throws Exception {
    Class<? extends MultipleBoundedWildcardEquality> clazz = MultipleBoundedWildcardEquality.class;
    Method method = clazz.getDeclaredMethod("multipleBoundedWildcardEquality", Pair.class);
    TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
    assertLenghtOne(typeParameters);
    TypeVariable<?> typeParameter = typeParameters[0];
    Type[] typeParameterBounds = typeParameter.getBounds();
    assertEquals(2, typeParameterBounds.length);
    assertEquals(Object.class, typeParameterBounds[0]);
    assertInstanceOf(ParameterizedType.class, typeParameterBounds[1]);
    ParameterizedType parameterizedType = (ParameterizedType) typeParameterBounds[1];
    assertEquals(Comparable.class, parameterizedType.getRawType());
    Type[] typeArguments = parameterizedType.getActualTypeArguments();
    assertLenghtOne(typeArguments);
    assertInstanceOf(ParameterizedType.class, typeArguments[0]);
    ParameterizedType type = (ParameterizedType) typeArguments[0];
    assertEquals(typeParameter, type.getActualTypeArguments()[0]);
    assertEquals(MultipleBoundedWildcardEquality.class, type.getRawType());
    Type[] parameterTypes = method.getGenericParameterTypes();
    assertLenghtOne(parameterTypes);
    Type parameter = parameterTypes[0];
    assertInstanceOf(ParameterizedType.class, parameter);
    ParameterizedType paramType = (ParameterizedType) parameter;
    Type[] actualTypeArguments = paramType.getActualTypeArguments();
    assertEquals(2, actualTypeArguments.length);
    Type firstArgument = actualTypeArguments[0];
    assertInstanceOf(WildcardType.class, firstArgument);
    WildcardType firstWildcardArgument = (WildcardType) firstArgument;
    Type secondArgument = actualTypeArguments[1];
    assertInstanceOf(WildcardType.class, secondArgument);
    WildcardType secondWildcardArgument = (WildcardType) secondArgument;
    assertEquals(firstWildcardArgument, secondWildcardArgument);
    Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
    assertLenghtOne(firstWildcardArgumentUpperBounds);
    Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
    Type[] secondWildcardArgumentUpperBounds = secondWildcardArgument.getUpperBounds();
    assertLenghtOne(secondWildcardArgumentUpperBounds);
    Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentUpperBounds[0];
    assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) WildcardType(java.lang.reflect.WildcardType) WildcardType(java.lang.reflect.WildcardType) TypeVariable(java.lang.reflect.TypeVariable) Method(java.lang.reflect.Method)

Example 75 with TypeVariable

use of java.lang.reflect.TypeVariable in project robovm by robovm.

the class OldGenericTypesTest method testMultipleGenericTypes.

@SuppressWarnings("unchecked")
public void testMultipleGenericTypes() throws Exception {
    //Type parameters
    Class<? extends MultipleGenericTypes> clazz = MultipleGenericTypes.class;
    TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
    assertEquals(2, typeParameters.length);
    TypeVariable<?> typeVariableT = typeParameters[0];
    assertEquals(clazz, typeVariableT.getGenericDeclaration());
    assertEquals("T", typeVariableT.getName());
    TypeVariable<?> typeVariableS = typeParameters[1];
    assertEquals("S", typeVariableS.getName());
    assertEquals(clazz, typeVariableS.getGenericDeclaration());
    // multipleGenericTypesT
    Method multipleGenericTypesT = clazz.getDeclaredMethod("multipleGenericTypesT", new Class[] { Object.class });
    Type[] multipleGenericTypesTTypes = multipleGenericTypesT.getGenericParameterTypes();
    assertLenghtOne(multipleGenericTypesTTypes);
    Type multipleGenericTypesTType = multipleGenericTypesTTypes[0];
    assertEquals(typeVariableT, multipleGenericTypesTType);
    // multipleGenericTypesS
    Method multipleGenericTypesS = clazz.getDeclaredMethod("multipleGenericTypesS", new Class[] { Object.class });
    Type[] multipleGenericTypesSTypes = multipleGenericTypesS.getGenericParameterTypes();
    assertLenghtOne(multipleGenericTypesSTypes);
    Type multipleGenericTypesSType = multipleGenericTypesSTypes[0];
    assertEquals(typeVariableS, multipleGenericTypesSType);
    // multipleGenericTypesS
    Method multipleGenericTypesTS = clazz.getDeclaredMethod("multipleGenericTypesTS", new Class[] { Object.class, Object.class });
    Type[] multipleGenericTypesTSTypes = multipleGenericTypesTS.getGenericParameterTypes();
    assertEquals(2, multipleGenericTypesTSTypes.length);
    Type multipleGenericTypesTSTypeT = multipleGenericTypesTSTypes[0];
    assertEquals(typeVariableT, multipleGenericTypesTSTypeT);
    Type multipleGenericTypesTSTypeS = multipleGenericTypesTSTypes[1];
    assertEquals(typeVariableS, multipleGenericTypesTSTypeS);
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) TypeVariable(java.lang.reflect.TypeVariable) Method(java.lang.reflect.Method)

Aggregations

TypeVariable (java.lang.reflect.TypeVariable)218 Type (java.lang.reflect.Type)169 ParameterizedType (java.lang.reflect.ParameterizedType)168 GenericArrayType (java.lang.reflect.GenericArrayType)122 WildcardType (java.lang.reflect.WildcardType)100 Method (java.lang.reflect.Method)44 ArrayList (java.util.ArrayList)18 HashMap (java.util.HashMap)11 GenericDeclaration (java.lang.reflect.GenericDeclaration)8 List (java.util.List)8 Map (java.util.Map)8 ElementType (java.lang.annotation.ElementType)7 Field (java.lang.reflect.Field)7 IOException (java.io.IOException)6 AccessibleObject (java.lang.reflect.AccessibleObject)6 MediaType (javax.ws.rs.core.MediaType)6 CompositeType (org.apache.flink.api.common.typeutils.CompositeType)6 TypeExtractionUtils.isClassType (org.apache.flink.api.java.typeutils.TypeExtractionUtils.isClassType)6 Test (org.junit.Test)6 VisibleForTesting (com.google.common.annotations.VisibleForTesting)5