传递参数通常在hashmap中实现方法

时间:2014-09-29 09:05:23

标签: java generics design-patterns reflection hashmap

我正在关注这个问题 How to generically implement calling methods stored in a HashMap? 我正在尝试在调用executeCommand时传递参数 功能 示例代码如下, 的 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;
}

}

终端

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
 }
}

主要

    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;
    }
}

更新 我正在尝试使用setCommand设置多个方法并执行它。

commandline.setCommand('p',this.getClass().getDeclaredMethod("parseData",String.class,Integer.class), this);
commandline.setCommand('p', this.getClass().getDeclaredMethod("test"), this);

然后,拨打

commandline.executeCommand('p', "test", 2345);

只有测试函数正在调用。(上一个setCommand函数正在运行)。我认为这是覆盖Method。是不是有人在setCommand函数中传递多个方法。将Method的类型更改为Method[]也无效。

2 个答案:

答案 0 :(得分:1)

调用方法时,需要传递应该调用方法的实例以及参数:

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;

}

这是一个实现:

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);
    }

}

然后你的终端:

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);
    }

}

最后在你的主要:

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");
}

请注意,静态方法不需要实例,因为它们属于类,例如:

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);
}

同时查看https://stackoverflow.com/a/542122/1225328https://stackoverflow.com/a/1348228/1225328

答案 1 :(得分:0)

MethodObject,您必须使用reflection。我在代码中看到问题时,您无法使用方法{Method对象获取1}}。在invocation课程中进行更改。检查 javadoc here ,以便从Main {{获取Method Object 1}}(对于类Object,您可以使用ClassObject

Class.forName(String class_binary_name)

另外,如果您不打算返回任何内容,请将测试类的返回类型更改为void