Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using java.lang.reflect.getMethod with polymorphic methods

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?

like image 864
Joonas Pulakka Avatar asked Jun 21 '10 10:06

Joonas Pulakka


2 Answers

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;
        }
     }
like image 100
stacker Avatar answered Sep 22 '22 07:09

stacker


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.

like image 34
user207421 Avatar answered Sep 21 '22 07:09

user207421