views:

61

answers:

2

Consider the following snippet:

public class ReflectionTest {

    public static void main(String[] args) {

        ReflectionTest test = new ReflectionTest();
        String object = new String("Hello!");

        // 1. String is accepted as an Object
        test.print(object);

        // 2. The appropriate method is not found with String.class
        try {
            java.lang.reflect.Method print
                = test.getClass().getMethod("print", object.getClass());
            print.invoke(test, object);
        } catch (Exception ex) {
            ex.printStackTrace(); // NoSuchMethodException!
        }
    }

    public void print(Object object) {
        System.out.println(object.toString());
    }

}

getMethod() is obviously unaware that a String could be fed to a method that expects an Object (indeed, it's documentation says that it looks for method with the specified name and exactly the same formal parameter types).

Is there a straightforward way to find methods reflectively, like getMethod() does, but taking polymorphism into account, so that the above reflection example could find the print(Object) method when queried with ("print", String.class) parameters?

+4  A: 

The reflection tutorial

suggest the use of Class.isAssignableFrom() sample for finding print(String)

    Method[] allMethods = c.getDeclaredMethods();
    for (Method m : allMethods) {
        String mname = m.getName();
        if (!mname.startsWith("print") {
            continue;
        }
        Type[] pType = m.getGenericParameterTypes();
        if ((pType.length != 1)
            || !String.class.isAssignableFrom(pType[0].getClass())) {
            continue;
        }
     }
stacker
+1  A: 

The easy way to do this is via java.beans.Statement or java.beans.Expression. Does all these hard yards for you.

getMethod() is obviously unaware that a String could be fed to a method that expects an Object

'Unaware' is a strange way to put it. getMethod() adheres to its specification. You have to supply the formal parameters, not the types of the actual arguments.

EJP