我有一个ArrayList,希望能够调用索引并使用返回的字符串进行方法调用。
e.g。
stringList.get(2)();
我有什么方法可以解决这个问题吗?
答案 0 :(得分:11)
答案 1 :(得分:2)
是,有一种方法可以使用列表中返回的字符串进行方法调用。
正如其他用户已经指出的那样,您需要使用Reflection API 。可能是复杂的处理,取决于你面临的特定情况。
为了向您展示具体的基本方法,但简化示例,我创建了此代码。复制它并播放更改索引,并在了解API的基础知识后创建带参数的新方法。
import java.lang.reflect.*;
import java.util.*;
public class DemoReflection {
public static void main(String[] args) {
List<String> myStringList = new ArrayList<String>();
myStringList.add(0, "foo");
myStringList.add(1, "printStr");
myStringList.add(2, "otherMethod");
myStringList.add(3, "stackoverflow");
int index = 3;
String methodName = myStringList.get(index);
try {
Class<?> c = Class.forName("DemoReflection");
Object obj = c.newInstance();
Method method = c.getDeclaredMethod(methodName, null);
method.invoke(obj, null);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
public void stackoverflow() {
System.out.println("Stackoverflow rules!");
}
public void printStr() {
System.out.println("Method printStr invoked...");
}
}
答案 2 :(得分:1)
答案 3 :(得分:1)
ArrayList 是否包含字符串? 否则,您可以使用java.lang.reflect.Method实例填充它,并在返回的实例上调用Method.invoke()。
答案 4 :(得分:1)
如果我了解您的需求,这里有一个基于界面的示例;然后列表包含接口的实现而不是方法名称:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws Exception {
List<Action> actions = new ArrayList<Action>();
actions.add(new Action(){
public void execute() {
System.out.println("Action 0");
}});
actions.add(new Action(){
public void execute() {
System.out.println("Action 1");
}});
actions.get(0).execute();
actions.get(1).execute();
}
static interface Action{
void execute();
}
}
答案 5 :(得分:1)
首先调用你不能在没有对象的情况下调用java中的方法来调用它。这也在列表中。
最好有一个Runnable列表...
List<Runnable> runnables = ...
runnables.get(2).call();
如果你有需要调用的对象,并且想要使用反射(可能很慢),那么commons-beans可以帮助简化它。见http://commons.apache.org/beanutils
import org.apache.commons.beanutils.MethodUtils;
Object target = ...
List<String> methodNames = ...
MethodUtils.invokeMethod(target, methodNames.get(2), /*args*/ null);
为了给我更好的建议,我需要更多地了解你要解决的问题。
答案 6 :(得分:0)
或许多态性和工厂方法可能是一个更好的主意。你必须限制你能够调用的方法,但这不是一个坏主意。
如果你想要完整的Monty,并且你正在使用Java 6,也许你可以创建一个JavaScript函数对象并使用Rhino调用它。
答案 7 :(得分:0)
或者如果你坚持让这个想法无论遇到什么障碍都可以工作,你可以使用像JRuby或Clojure这样的动态语言,这两种语言都愿意eval()
一个字符串。
或Jython或Groovy或......
答案 8 :(得分:0)
在Java中 - 没办法。这不是Java语言功能。你希望得到像
这样的东西// NOT VALID JAVA
String myColoring = paintBlackOrWhite() ? "black" : "white";
myColoring(myBathroomWall);
// NOT VALID JAVA
与其他建议一样,纯技术解决方案将使用反射:获取结果字符串,找到相应的方法并调用它。技术解决方案甚至可以是像
这样的地图Map<String, java.lang.reflect.Method> myMethods;
并执行类似
的操作get("black").invoke(myObject, myParams);
但所有这些都很好知道,你不应该使用它,除非被迫或你有一个具体的问题,即使SO没有解决方案;)