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;
}
}
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();
}
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);
}
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);
}
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);
}
Aggregations