Reputation: 801
I am following this question
How to generically implement calling methods stored in a HashMap?
I am trying to pass parameters while calling executeCommand
function
Example code is as follows,
InvokesMethodItf
public interface InvokesMethodItf {
public void invokeMethod(String data) throws Exception; //pass the data as parameter
public void setMethod(Method method);
}
InvokesMethod
public class InvokesMethod implements InvokesMethodItf{
private Method method;
@Override
public void invokeMethod(String data) throws Exception {
method.invoke(data); //pass the data to invoke (I think my problem is here). I dont know how to pass it.
}
@Override
public void setMethod(Method method) {
this.method = method;
}
}
Terminal
public class Terminal {
public HashMap<Character, InvokesMethodItf> commands;
public Terminal() {
this.commands = new HashMap<Character, InvokesMethodItf>();
}
private void setCommand(char letter, Method method) {
InvokesMethodItf inv = new InvokesMethod();
inv.setMethod(method);
this.commands.put(letter, inv);
}
public void executeCommand(char letter, String data) throws Exception {
this.commands.get(letter).invokeMethod(data); //pass data to invoke method
}
}
Main
public class Main {
Terminal commandLine = new Terminal();
commandLine.setCommand('h',test()); //This should give syntax error or i am not sure
commandLine.executeCommand('h', "This is a test");
public Method test(String data){
Log.d("Test", data);
return null;
}
}
UPDATE: I am trying to set multiple methods using setCommand and execute it.
commandline.setCommand('p',this.getClass().getDeclaredMethod("parseData",String.class,Integer.class), this);
commandline.setCommand('p', this.getClass().getDeclaredMethod("test"), this);
Then , calling
commandline.executeCommand('p', "test", 2345);
Only test function is calling.(Last setCommand function is running). I think it is overwriting Method
. Isn't there is someway to pass multiple methods in setCommand function. Changing type of Method
to Method[]
is not working either.
Upvotes: 1
Views: 1231
Reputation: 48837
When invoking a method, you need to pass the instance from which the method should be invoked as well as the parameters:
public interface MethodInvoker {
// the method + the instance from which the method should be called
public void setMethod(Method method, Object instance);
// invokes the method
public void invoke(Object... params) throws Exception;
}
Here an implementation:
public class MethodInvokerImpl implements MethodInvoker {
private Method method;
private Object instance;
@Override
public void setMethod(Method method, Object instance) {
this.method = method;
this.instance = instance;
}
@Override
public void invoke(Object... params) throws Exception {
// first param: instance, then the parameters
method.invoke(instance, params);
}
}
Then your Terminal:
public class Terminal {
public Map<Character, MethodInvoker> commands;
public Terminal() {
commands = new HashMap<Character, MethodInvoker>();
}
// instance needed, since MethodInvoker#setMethod needs it
public void addCommand(char letter, Method method, Object instance) {
MethodInvoker invoker = new MethodInvokerImpl();
invoker.setMethod(method, instance);
commands.put(letter, invoker);
}
public void executeCommand(char letter, Object... params) throws Exception {
commands.get(letter).invoke(params);
}
}
Finally in your main:
public void test(String data) {
System.out.println(data);
}
public void main() throws Exception {
Terminal commandLine = new Terminal();
// #text() will be called from "this" instance
commandLine.addCommand('h', getClass().getMethod("test", String.class), this);
commandLine.executeCommand('h', "This is a test");
}
Note that static methods don't need instances since they belong to the class, e.g.:
public void main() throws Exception {
Terminal commandLine = new Terminal();
// simply pass "null" as instance
commandLine.addCommand('h', getClass().getMethod("test", String.class), null);
commandLine.executeCommand('h', "This is a test");
}
public static void test(String data) {
System.out.println(data);
}
See https://stackoverflow.com/a/542122/1225328 and https://stackoverflow.com/a/1348228/1225328 as well.
Upvotes: 1
Reputation: 6675
Method
is an Object
which you will have to get using reflection
.As I see the problems in your code,you cannot get Method
Object using method invocation
.Change this in your Main
class.Check the javadoc here for getting Method
Object
from Class
Object
(for class Object you can use Class.forName(String class_binary_name)
or Class literal
public class Main {
Terminal commandLine = new Terminal();
Method method = Main.class.getMethod("test",String.class);
commandLine.setMethod('h',method);
commandLine.executeCommand('h', "This is a test");
public void test(String data){
Log.d("Test", data);
}
}
Also,change the return type of test class to void if you are not planning to return anything
Upvotes: 0