Reputation: 707
I have a method that helps to invoke a known method
public static void invoke(Object object, Class<?> callingClass, String methodName, Object[] param)
I was able to invoke this
for (Method method : callingClass.getDeclaredMethods()) {
if (method.getName().equals("bla")) {
method.invoke(object, param);
}
}
But when I tried to call
Class[] paramClass = new Class[param.length];
for (int i = 0; i < paramClass.length; i++) {
paramClass[i] = Class.forName(param[i].getClass().getName());
}
Method method = callingClass.getDeclaredMethod(methodName, paramClass);
I encountered java.lang.NoSuchMethodException. The method that I tried to invoke is
public void bla(String[] arg, Map<String, String[]> argContext);
And I passed in my "invoke" method the above, just for the param, an array consists of a String[] object, and a Map object retrieved from Collections.unmodifiableMap(source)
I guess the problem comes from the fact that my input is UnmodifiableMap where the bla method requires a regular Map. What's the work around for this? Thanks
Upvotes: 1
Views: 1190
Reputation: 16932
The problem is, that getDeclaredMethod
does not do the polymorphism for you. You have to explicitly go though all super-classes and interfaces of your parameter(s) and check for every possible signature.
That is, for class C extends B
and class B extends A
you have to check for method(C c)
, method(B b)
and method(A a)
(if you find any, it can be invoked with an argument of type C).
You actually have to calculate the "distance" yourself and decide what is the best suited implementation: If you find an implementation method(B,A) and an implementation method(A,B) and you like to call it with the argument (C,C), then it is up to you to decide which method applies, i.e., you either call getDeclaredMethod(A.class, B.class) or getDeclaredMethod(B.class, A.class) and both could be invoked with your argument of type (C,C).
Upvotes: 2
Reputation: 82461
Map
is an interface. Therefore every instance of a Map
has a concrete class different to Map.class
, and the getClass()
method doesn't return Map.class
. But for the Class
that is actually returned, there is no method that matches the signature.
Also you may want to change
Class.forName(param[i].getClass().getName())
to
param[i].getClass()
Upvotes: 1