如何一般地实现存储在HashMap中的调用方法?

时间:2013-09-28 05:05:15

标签: java design-patterns reflection hashmap anonymous-class


我想将某些字符路由到方法,以便在命令行中键入char时,然后执行该方法。

基于答案How to call a method stored in a HashMap,我通过使用“命令”设计模式将这些字符映射到方法。

但是我想一般地实现它,所以我似乎需要实现反射才能使用Method类作为参数。我的尝试是在我的匿名课程中获得NullPointerException字段private Method method ...

<小时/> 这是我的代码:

import java.lang.reflect.Method;

public interface InvokesMethod {

    public void invokeMethod() throws Exception;
    public void setMethod(Method method);
} // end of interface


import java.util.HashMap;
import java.lang.reflect.Method;

public class Terminal {

    public HashMap<Character, InvokesMethod> commands;

    public Terminal() {
        this.commands = new HashMap<Character, InvokesMethod>();

        try {
            this.setCommand('p',
                 this.getClass().getDeclaredMethod("printHelloWorld"));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void printHelloWorld() {
        System.out.println("Hello World!");
    }

    private void setCommand(char letter, Method method) {
        this.commands.put(letter, new InvokesMethod() {

            // NullPointerException starts here in the stack-trace:
            private Method method;

            @Override
            public void invokeMethod() throws Exception {
                method.invoke(null);
            }

            @Override
            public void setMethod(Method method) {
                this.method = method;
            }
        }).setMethod(method);
    }

    public void executeCommand(char letter) throws Exception {
        this.commands.get(letter).invokeMethod();
    }
} // end of class


public class Main() {

    public static void main(String[] args) {
        Terminal commandLine = new Terminal();

        try {
            commandLine.executeCommand('p');

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
} // end of class

2 个答案:

答案 0 :(得分:1)

关于您的代码,您没有发起method。请记住,executenull您必须调用公共静态方法:

您的其他问题,您没有正确启动界面。这是一个有效的例子:

<强> InvokesMethodItf

public interface InvokesMethodItf {

public void invokeMethod() throws Exception;
public void setMethod(Method method);
} 

<强> InvokesMethod

public class InvokesMethod implements InvokesMethodItf{

private Method method;

@Override
public void invokeMethod() throws Exception {
     method.invoke(null);
}

@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>();

    try {
        this.setCommand('p',
             this.getClass().getDeclaredMethod("printHelloWorld"));

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void printHelloWorld() {// method.invoke(null) looking for "static" method
    System.out.println("Hello World!");
}


private void setCommand(char letter, Method method) {

    InvokesMethodItf inv = new InvokesMethod();

    inv.setMethod(method);

    this.commands.put(letter, inv);
}

public void executeCommand(char letter) throws Exception {
    this.commands.get(letter).invokeMethod();
 }
}

主要

public class Main {
public static void main(String[] args) {
    Terminal commandLine = new Terminal();

    try {
        commandLine.executeCommand('p');

    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}

输出:

Hello World!

答案 1 :(得分:0)


感谢@Maxim的原始建议,我有一个替代解决方案,通过在HashMap中将方法设置为字符串 -

import java.util.HashMap;
import java.lang.reflect.Method;

public class Terminal {

    private HashMap<Character, String> commands;

    public Terminal() {
        this.commands = new HashMap<Character, String>();
        this.commands.put('p', "printHelloWorld");
    }

    private void printHelloWorld() {
        System.out.println("Hello World!");
    }

    public void executeCommand(char letter) throws Exception {
        Method method = getClass().getDeclaredMethod(this.commands.get(letter));
        method.invoke(this);
    }


public class Main {
    public static void main(String[] args) {
        Terminal commandLine = new Terminal();

        try {
            commandLine.executeCommand('p');

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
} // end of class


输出:

Hello World!

<小时/> 现在想弄清楚如何将参数传递给反射方法......