Sam Brannen opened SPR-8644 and commented
Status Quo
ReflectionUtils.findMethod(Class<?>, String, Class<?>...)
currently only finds methods with exact matches for supplied the argument types. findMethod()
also does not find methods that accept variable arguments (see ReflectionUtilsTests.findMethodWithVarArgs()
for an example of a failing test).
MethodInvoker
on the other hand finds methods with compatible argument types.
As an aside, invokeMethod(Object, String, Object...)
in ReflectionTestUtils
could not be implemented using ReflectionUtils
due to these limitations.
Deliverable
Either modify ReflectionUtils.findMethod(Class<?>, String, Class<?>...)
or introduce a new method in ReflectionUtils
to provide support for finding methods with compatible argument lists, specifically:
- for methods that accepts var-args
- for example, a call to
findMethod(clazz, "add", int.class, int.class, int.class)
should find a a method named "add" with a parameter declaration of(int... args)
. - of course, a call to
findMethod(clazz, "add", new int[] {int.class, int.class, int.class})
will find the var-args method, but this requires specific knowledge of the implementation and therefore does not lend itself to dynamic, reflective use cases. - with regard to type conversion, either due automatic boxing and unboxing of primitives or due to inheritance.
- for example, a call to
findMethod(clazz, "foo", Integer.class)
should find a method named "foo" that accepts anint
. For example, the following unit test should pass.
public class Test {
public void foo(int a) {
System.out.println("a = " + a);
}
@Test
public void testFoo() {
Method method = ReflectionUtils.findMethod(getClass(), "foo", Integer.class);
assertNotNull(method);
}
}
- similarly, a call to
findMethod(clazz, "foo", Integer.class)
should find a method named "foo" that accepts aNumber
if there is no "foo" method that accepts anInteger
.
Affects: 3.0.6
Attachments: - ReflectionUtils.java.patch (3.31 kB)
Issue Links: - #13275 Introduce a generic method for invoking any non-public method in ReflectionTestUtils
Referenced from: commits https://github.com/spring-projects/spring-framework/commit/16fb3cb4b3fe6db341277889b20a2e4f774e2cc4, https://github.com/spring-projects/spring-framework/commit/1a34f6459d0e49e4fd60aa3644ad17fa117854d9
2 votes, 3 watchers
Comment From: spring-projects-issues
Sean Patrick Floyd commented
Here's a patch that implements this functionality. I have often missed this myself.
Comment From: spring-projects-issues
Sean Patrick Floyd commented
Of course I would also welcome if this line vanished from the Apidocs: "Only intended for internal use."
I think ReflectionUtils is great, and I know of no equivalent Utility class for Reflection in the usual utility libraries.
Comment From: spring-projects-issues
Sam Brannen commented
Sean,
Thanks for submitting the patch; we'll consider it. Note, however, that Spring's MethodInvoker
already has this functionality.
Also, your implementation handles case #2 above (i.e., assignable from), but it does not support var-args. I've modified this issue to address var-args as well; however, it may turn out that support for var-args warrants a separate issue.
Cheers,
Sam
Comment From: spring-projects-issues
Sean Patrick Floyd commented
Sam,
I agree, the code in MethodInvoker is better. Perhaps you should refactor that to make it accessible in static way (and move the code to ReflectionUtils or ClassUtils).
Sean
Comment From: spring-projects-issues
Juergen Hoeller commented
Closing groups of outdated issues. Please reopen if still relevant.