You need to follow the same process as described in the Java Language Specification, Section 15.12, βMethod Call Expressions,β to search for the same method that will be found at compile time. In short, it is harder than you think.
A simple option would be to test all methods with the correct name (and do not forget about the methods of all superclasses). For each of these methods, check if all your arguments are compatible with the corresponding method parameter. This may not be perfect, but it works in most cases.
[Update:] The "simple option" fails if there are several overloaded methods in the class. Here is a sample code you can play with:
package so7691729; import static org.junit.Assert.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.Set; import org.junit.Test; import com.google.common.collect.Maps; import com.google.common.collect.Sets; public class MethodCaller { private boolean isCompatible(Method m, Object... args) { Class<?>[] parameterTypes = m.getParameterTypes(); if (parameterTypes.length == args.length) { for (int i = 0; i < args.length; i++) { if (args[i] != null) { if (!parameterTypes[i].isAssignableFrom(args[i].getClass())) { clazz = Class.forName(className); for (Class<?> c = clazz; c != null; c = c.getSuperclass()) { Set<String> sameNameMethods = Sets.newTreeSet(); Map<String, Method> compatibleMethods = Maps.newTreeMap(); for (Method method : c.getDeclaredMethods()) { if (method.getName().equals(methodName)) { sameNameMethods.add(method.toString()); if (isCompatible(method, args)) { compatibleMethods.put(method.toString(), method); } } } if (compatibleMethods.size() > 1) { throw new IllegalArgumentException("Multiple candidates: " + compatibleMethods.keySet()); } if (compatibleMethods.size() == 1) { return compatibleMethods.values().iterator().next().invoke(obj, args); } if (!sameNameMethods.isEmpty()) { throw new IllegalArgumentException("Incompatible types for " + sameNameMethods); } } throw new IllegalArgumentException("No method found."); } public Object call(String fullyQualifiedMethodName, Object obj, Object... args) { try { return call1(fullyQualifiedMethodName, obj, args); } catch (ClassNotFoundException e) { throw new IllegalArgumentException(e); } catch (IllegalAccessException e) { throw new IllegalArgumentException(e); } catch (InvocationTargetException e) { throw new IllegalArgumentException(e); } } public String str(Object obj) { return "object " + obj; } public String str(String str) { return "string " + str; } public int add(int a, int b) { return a + b; } @SuppressWarnings("boxing") public int addObj(Integer a, Integer b) { return a + b; } private void assertCallingError(String msg, String methodName, Object obj, Object... args) { try { call(methodName, obj, args); fail(); } catch (IllegalArgumentException e) { assertEquals(msg, e.getMessage()); } } @SuppressWarnings("boxing") @Test public void test() { MethodCaller dummy = new MethodCaller(); assertEquals("object 1", call("so7691729.MethodCaller.str", dummy, 1)); assertCallingError("Multiple candidates: " +
And perhaps the specification or implementation of Java Beans has something for you. They may have had the same problem. Or look at Rhino, a JavaScript implementation in pure Java. It allows you to call Java methods directly from JavaScript code, so this is very similar to your problem.