Introduce GenericTypeResolver#resolveReturnTypeArgument
Issue: SPR-8514 git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4680 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
075dfc3cb4
commit
de5781acea
|
|
@ -24,6 +24,8 @@ import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.lang.reflect.TypeVariable;
|
import java.lang.reflect.TypeVariable;
|
||||||
|
import java.lang.reflect.WildcardType;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -102,6 +104,35 @@ public abstract class GenericTypeResolver {
|
||||||
return (rawType instanceof Class ? (Class) rawType : method.getReturnType());
|
return (rawType instanceof Class ? (Class) rawType : method.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the single type argument of the given generic interface against the given
|
||||||
|
* target method which is assumed to return the given interface or an implementation
|
||||||
|
* of it.
|
||||||
|
* @param method the target method to check the return type of
|
||||||
|
* @param genericIfc the generic interface or superclass to resolve the type argument from
|
||||||
|
* @return the resolved parameter type of the method return type, or <code>null</code>
|
||||||
|
* if not resolvable or if the single argument is of type {@link WildcardType}.
|
||||||
|
*/
|
||||||
|
public static Class<?> resolveReturnTypeArgument(Method method, Class<?> genericIfc) {
|
||||||
|
Type returnType = method.getReturnType();
|
||||||
|
Type genericReturnType = method.getGenericReturnType();
|
||||||
|
ParameterizedType targetType;
|
||||||
|
if (returnType.equals(genericIfc)) {
|
||||||
|
if (genericReturnType instanceof ParameterizedType) {
|
||||||
|
targetType = (ParameterizedType)genericReturnType;
|
||||||
|
Type[] actualTypeArguments = targetType.getActualTypeArguments();
|
||||||
|
Type typeArg = actualTypeArguments[0];
|
||||||
|
if (!(typeArg instanceof WildcardType)) {
|
||||||
|
return (Class<?>)typeArg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GenericTypeResolver.resolveTypeArgument((Class<?>)returnType, genericIfc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the single type argument of the given generic interface against
|
* Resolve the single type argument of the given generic interface against
|
||||||
* the given target class which is assumed to implement the generic interface
|
* the given target class which is assumed to implement the generic interface
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import java.util.Collection;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
|
@ -46,6 +47,14 @@ public class GenericTypeResolverTests {
|
||||||
assertEquals(Collection.class, GenericTypeResolver.resolveTypeArgument(MyCollectionSuperclassType.class, MySuperclassType.class));
|
assertEquals(Collection.class, GenericTypeResolver.resolveTypeArgument(MyCollectionSuperclassType.class, MySuperclassType.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMethodReturnType() {
|
||||||
|
assertEquals(Integer.class, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "integer"), MyInterfaceType.class));
|
||||||
|
assertEquals(String.class, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "string"), MyInterfaceType.class));
|
||||||
|
assertEquals(null, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "raw"), MyInterfaceType.class));
|
||||||
|
assertEquals(null, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "object"), MyInterfaceType.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface MyInterfaceType<T> {
|
public interface MyInterfaceType<T> {
|
||||||
}
|
}
|
||||||
|
|
@ -66,4 +75,12 @@ public class GenericTypeResolverTests {
|
||||||
public class MyCollectionSuperclassType extends MySuperclassType<Collection<String>> {
|
public class MyCollectionSuperclassType extends MySuperclassType<Collection<String>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MyTypeWithMethods {
|
||||||
|
public MyInterfaceType<Integer> integer() { return null; }
|
||||||
|
public MySimpleInterfaceType string() { return null; }
|
||||||
|
public Object object() { return null; }
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public MyInterfaceType raw() { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue