Assume a declaration like the following where you need to identify the one method parameter where the generic type matches the return type of the method.
interface SomeRepository {
<T> T someMethod1(Class<T> arg0, Class<?> arg1, Class<Object> arg2);
}
Method method = ReflectionUtils.findMethod(SomeRepository.class, "someMethod1", Class.class, Class.class, Class.class);
ResolvableType returnType = ResolvableType.forMethodReturnType(method, SomeRepository.class);
ResolvableType arg0 = ResolvableType.forMethodParameter(method, 0, SomeRepository.class); // generic[0]=T
ResolvableType arg1 = ResolvableType.forMethodParameter(method, 1, SomeRepository.class); // generic[0]=?
ResolvableType arg2 = ResolvableType.forMethodParameter(method, 2, SomeRepository.class); // generic[0]=java.lang.Object
assertThat(returnType.isAssignableFrom(arg0.as(Class.class).getGeneric(0))).isTrue();
assertThat(returnType.isAssignableFrom(arg1.as(Class.class).getGeneric(0))).isFalse();
assertThat(returnType.isAssignableFrom(arg2.as(Class.class).getGeneric(0))).isFalse();
Comment From: jhoeller
I'm afraid isAssignableFrom
is actually right for its purposes there, considering the Object
argument as assignable to the Object-resolved type variable. That algorithm isn't really meant to be used for differentiating such arguments to begin with.
One could replace this with straight ResolvableType.equals
- but the problem there is the internal type provider reference that the ResolvableType
is holding, making it non-equal between the method return wrapper and the extracted generic.
That said, replacing the check with a comparison of ResolvableType.getType()
seems to exhibit the desired characteristics:
assertThat(returnType.getType().equals(arg0.as(Class.class).getGeneric(0).getType())).isTrue();
assertThat(returnType.getType().equals(arg1.as(Class.class).getGeneric(0).getType())).isFalse();
assertThat(returnType.getType().equals(arg2.as(Class.class).getGeneric(0).getType())).isFalse();
We could introduce a ResolvableType.equalsType(ResolvableType)
convenience method for this if this is common enough...