问题
I want to route certain chars to methods, so that when the char is typed in the command-line the method is then executed.
Based on the answer How to call a method stored in a HashMap, I'm mapping these chars to methods by using the "Command" design-pattern.
However I want to generically implement this, so it seems that I need to implement reflection in order to use the Method
class as a parameter. My attempt is getting a NullPointerException
on the field private Method method
in my anonymous class...
Here is my code:
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
回答1:
Regards to your code you didn't initiate method
. Bear in mind that execute
with null
you must call public static method:
Your other issue , you didn't initiated interface properly. Here is working example:
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;
}
}
Terminal
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();
}
}
Main
public class Main {
public static void main(String[] args) {
Terminal commandLine = new Terminal();
try {
commandLine.executeCommand('p');
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
Hello World!
回答2:
Thanks to @Maxim's original suggestion here, I have an alternate solution by setting the methods as Strings in the HashMap instead --
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
Output:
Hello World!
Now to figure out how to pass parameters to the reflected methods...
来源:https://stackoverflow.com/questions/19063522/how-to-generically-implement-calling-methods-stored-in-a-hashmap