使用返回的字符串来调用方法?

时间:2009-11-26 12:18:34

标签: java string arraylist

我有一个ArrayList,希望能够调用索引并使用返回的字符串进行方法调用。

e.g。

stringList.get(2)();

我有什么方法可以解决这个问题吗?

9 个答案:

答案 0 :(得分:11)

那么您希望将返回的String用作要调用的方法的名称吗?

你可以使用reflection来做到这一点,但我强烈反对这一点。

相反,您需要考虑实施strategy pattern

答案 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没有解决方案;)