Reputation: 37
I know how to use HashMaps
and stuff to map keys to values. I was just wondering if you could map keys to methods as well.
For example, a program asks the user for input. Then it calls a method that has its name as the input entered. ie: if the input is "cat"
, method cat()
is invoked.
Obviously one can use if statements, but is there an easier way?
Upvotes: 0
Views: 1249
Reputation: 687
You can do this using the Java Reflection API. Here is a basic example, although in practice you should make your exception catching logic more advanced:
public class JavaDynamicMethodsExample {
public void cat() {
System.out.println("Meow!");
}
public void dog() {
System.out.println("Bark!");
}
public void bird() {
System.out.println("Chirp!");
}
public void callMethod(String methodName) {
try {
Method method = this.getClass().getMethod(methodName);
method.invoke(this);
} catch (Exception e) {
System.out.println("Could not call method with name: " + methodName);
}
}
public static void main(String [] args) {
JavaDynamicMethodsExample example = new JavaDynamicMethodsExample();
String [] methods = {"cat", "dog", "hamster", "bird"};
for(String methodName : methods) {
example.callMethod(methodName);
}
}
}
This will output:
Meow!
Bark!
Could not call method with name: hamster
Chirp!
Upvotes: 1
Reputation: 30320
You can create Map
s of pretty much anything to anything. Your scenario is certainly an unorthodox application though.
But if you insist, you can just do this:
Map<String, Method> map = new HashMap<>(); //Java 7
Method[] methods = ClassToMap.class.getDeclaredMethods() //First link
for(Method m : methods) {
map.put(m.getName(), m); //Second link
}
And now you have a Map
of names of methods to methods you can then call--although you need to use the Method
API to call them.
Upvotes: 1
Reputation: 9304
Instead of trying to invoke specific method (which is not an object-oriented approach), you should create an interface with one method (or use Runnable
) and implement each invokable method in a separate class. Then put instance of these classes into map and invoke implemented method on the matching object:
Map<String, Runnable> myMap = new HashMap<String, Runnable>();
// fill myMap with your objects
String input = ...; // get user input
if (myMap.containsKey(input)) {
myMap.get(input).run();
}
Also, see strategy design pattern.
Upvotes: 1
Reputation: 1788
public class Test {
public static void main(String[] args) throws Exception {
String name = args[0];
Method method = Test.class.getDeclaredMethod(name, new Class[]{});
method.invoke(null, new Object[]{});
}
public static void method1() {
System.out.println("in method1()");
}
public static void method2() {
System.out.println("in method2()");
}
}
Upvotes: 1
Reputation: 81
You could do string to Method
.
For instance in your case, you can do something like:
String k = "cat"
String caller(String key)
{
String ret = null;
if (key.equals(k))
{
ret = cat();
}
return ret;
}
String cat() {}
So every time you pass an user's input to caller()
function, method cat()
is invoked.
Upvotes: -1
Reputation: 5637
Fetch the method and invoke it.
java.lang.reflect.Method method = class_obj.getClass().getMethod("functionName"); // add params if any
method.invoke(); // add params if any
This would be equivalent to calling the function
functionName(void);
This is for the case when you have to pass no parameters.
Upvotes: 2