views:

106

answers:

6

I would like to be able to call a function based on its name provided by a string. Something like

public void callByName(String funcName){
   this.(funcName)();
}

I have searched a bit into lambda funcions but they are not supported. I was thinking about going for Reflection, but I am a bit new to programming, so I am not so familiar with the subject.

This whole question was brought up on my java OOP class, when I started GUI (Swing, swt) programming, and events. I found that using object.addActionCommand() is very ugly, because I would later need to make a Switch and catch the exact command I wanted.

I would rather do something like object.attachFunction(btn1_click), so that it would call the btn1_click function when the event click was raised.

A: 

Check Class.forName() to get hold of a class definition for a given name.

If you have an interface containing the method you want to run, and the class implements this method then you can just create an instance, cast it to the interface and invoke the method.

If you cannot assume anything, use reflection on an instance of the class to get to the method you want, and invoke it with the arguments it needs. The Sun Tutorial has a nice section on reflection.

Thorbjørn Ravn Andersen
+1  A: 

You can use Class.getDeclaredMethod() to get the method with a specific name and parameters, then invoke the returned Method object:

Method method = MyClass.class.getDeclaredMethod("methodName", Event.class, String.class);
Object retVal = method.invoke(someEvent, someString);
Péter Török
+1  A: 

Yes, Reflection API can be used to do this, but I don't think this is the way to go for simple button event handling. Better ask for how this can be done elegantly in the GUI framework that you are using (Swing, SWT..), I'm sure there has to be a simpler way than Reflection.

Robert
+2  A: 

Java has methods, not functions. The difference is that methods have classes; you need to know the class to call the method. If it's an instance method, you need an instance to call it on, but OTOH it does mean that you can look the method up easily:

public void callByName(Object obj, String funcName) throws Exception {
    // Ignoring any possible result
    obj.getClass().getDeclaredMethod(funcName).invoke(obj);
}

Note that there are a lot of potential exceptions out of this and things get more complex if you want to pass arguments in.

If you are talking about a class method, what you do is slightly different:

public void callClassByName(Class cls, String funcName) throws Exception {
    // Ignoring any possible result
    cls.getDeclaredMethod(funcName).invoke(null);
}

You might also want to explore using a java.lang.reflect.Proxy.

Donal Fellows
A: 

The following code will call a public method of the given name, with no argument:

public void callByName(String funcName) {
    try {
        Method method = getClass().getDeclaredMethod(funcName);
        method.invoke(this, new Object[] {});
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}
Maurice Perry
+1  A: 

This question has been asked before. See here

Nishkar