10

I have a static method titled chooseDialog(String s, int i) in which I want to call another method within the same class (Dialogs.class) based on the parameters provided to chooseDialog. s is the name of the desired method and i is it's single parameter.

I have tried numerous tutorials and have spent a few hours reading up on the subject but I can't seem to get a firm grasp as to what exactly I need to do.

Any ideas?

Thanks!

Jared
  • 4,823
  • 6
  • 23
  • 15
  • Do you really need reflection? – dacwe Feb 04 '11 at 09:21
  • 1
    While there may be a good solution to you problem, it may be better to post the real problem your are trying to solve. E.g. why do you want to do this kind of method selection? Quite often someone can find a OOP design pattern that solve the underlying problem instead of find a par-force solution to the specific question. For example, the factory pattern may be what you need, allowing you to select classes, which then provide the required function as implementations of an abstract message. Do not let the details of your problem allow you to loose sight of the larger picture. – Ber Feb 04 '11 at 09:22
  • Each method in this class (other than chooseDialog) represents a series of unique actions, (10+ each) and this particular class consists of well over 300 methods to choose from. This just seemed to be the best route for me to go. Am I incorrect? Is there a better option? – Jared Feb 04 '11 at 09:26

4 Answers4

16

Why do you want to call a method with name passed in a String parameter? Cannot you create a constants for different actions, then use switch and in each case call the method with parameter i?

You will have the benefit of compiler checking your code for errors.

edit: if you really want to use reflection, retrieve a Method object with:

Method m = YourClass.class.getMethod("method_name",new Class[] { Integer.class }) 

I guess Integer.class might work. Then invoke the metod as

m.invoke(null,123); //first argument is the object to invoke on, ignored if static method
Axarydax
  • 16,353
  • 21
  • 92
  • 151
  • Each method in this class (other than chooseDialog) represents a series of unique actions, (10+ each) and this particular class consists of well over 300 methods to choose from. This just seemed to be the best route for me to go. Am I incorrect? Is there a better option? – Jared Feb 04 '11 at 09:30
  • 1
    If you are dealing with this huge number of methods, it's probably for the best. But I myself would be scared of typos. – Axarydax Feb 04 '11 at 10:09
  • You do not need to wrap the class parameters in an array; you can simply provide them as a list of arguments. For example: `YourClass.class.getMethod("method_name", Integer.class, String.class)`. – Paul Lammertsma Aug 01 '15 at 15:51
3
Method method = Dialogs.getMethod(s, Integer.class);
method.invoke(null, i);
Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
1

If you just want to call another static method on the class, then you can use the approach already identified by others:

Method method = Dialogs.getMethod(s, Integer.class);
method.invoke(null, i);

But if you want to be able to use a static method to call an non-static method, then you will need to pass in the object that you want to reference or make chooseDialog non-static.

function chooseDialog(Object o, String s, Integer i) {
    Method method = Dialogs.getMethod(o, Integer.class);
    method.invoke(o, i);
}

But I don't think that this is the correct OOP way to handle the problem. And based on your comments, reflection isn't absolutely necessary, and have chooseDialog analyze the string and pass that to the appropriate method is a much more typesafe approach. In either approach, your unit tests should look the same.

    if (s.equals("dialog1")) {
        dialog1(i);
    }
David
  • 61
  • 1
1

The following method will invoke the method and return true on success:

public static boolean invokeMethod(Object object,String methodName,Object... args)  {
    Class[] argClasses = new Class[args.length];
    try {
        Method m = object.getClass().getMethod(methodName,argClasses);
        m.setAccessible(true);
        m.invoke(object,args);
        return true;
    } catch (Exception ignore) {
        return false;
    }

}

Usage: invokeMethod(myObject,"methodName","argument1","argument2");

Gil SH
  • 3,789
  • 1
  • 27
  • 25