动态调用非静态方法

时间:2012-02-17 19:37:00

标签: java

我有几十个相互替代的功能。它们接受输入并返回输出,但在每种情况下输出略有不同。所有这些都嵌入在一个包装类中。

我想通过将方法名称作为字符串传递来调用它们。我还想避免手动维护大量不需要的if语句:

if(methodName.equals("method1")
    return method1(argument);
...
else if(methodName.equals("method176")
    return method176(argument);

到目前为止,我已经想出了如何动态调用这些方法,但前提是这些方法是静态的:

try {
    method = MyMainClass.class.getDeclaredMethod(methodName, MyArgumentClass.class);
    ResultClass result = (ResultClass)method.invoke(null, myArgument);
    return result;
}
catch(Exception e)
{
    e.printStackTrace();
    System.exit(1);
    return null;
}

对于非静态方法是否可以这样做,并在类实例而不是静态类上调用函数?

5 个答案:

答案 0 :(得分:5)

如果可能,最好避免反射。似乎可以使用Strategy pattern更好的设计解决您的问题。

答案 1 :(得分:5)

是。使用Java reflection只是传递实例来调用它作为invoke方法的第一个参数。

阅读:http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html#invoke

try {
    MyArgumentClass argument = new MyArgumentClass();
    MyMainClass instance = new MyMainClass(argument);
    method = MyMainClass.class.getDeclaredMethod(methodName, MyArgumentClass.class);
    ResultClass result = (ResultClass) method.invoke(instance, myArgument);
    return result;
}
catch(Exception e)
{
    e.printStackTrace();
    System.exit(1);
    return null;
}

正如其他答案所指出的,这不是解决问题的最佳方法。你应该这样实现the Strategy pattern

interface MyOperation{
   public ResultClass execute(MyArgumentClass argument);
}

public class Method1 implements MyOperation {
    public ResultClass execute(MyArgumentClass argument){
      ....
    }
}

public class Method176 implements MyOperation {
    public ResultClass execute(MyArgumentClass argument){
      ....
    }
}

public class DoIt{
    public ResultClass doIt(MyOperation method, MyArgumentClass argument){
       return method.doIt(argument);
    }
}

答案 2 :(得分:1)

是的,这是可能的。将要调用方法的对象作为invoke调用的第一个参数传入。在对象上调用getClass以获取要使用的类。

答案 3 :(得分:1)

获取您正在从类中检索的Method的实例,然后使用您希望调用该方法的类的实例调用Method.invoke()

如果你对这条路线感兴趣,你也可以使用Spring提供的一些bean来完成类似的事情。

答案 4 :(得分:1)

是的,可以这样做但你必须使用Java Reflection包java.lang.reflect。* 请查看此链接http://java.sun.com/developer/technicalArticles/ALT/Reflection/

中的“按名称调用方法”部分