我有几十个相互替代的功能。它们接受输入并返回输出,但在每种情况下输出略有不同。所有这些都嵌入在一个包装类中。
我想通过将方法名称作为字符串传递来调用它们。我还想避免手动维护大量不需要的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;
}
对于非静态方法是否可以这样做,并在类实例而不是静态类上调用函数?
答案 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/
中的“按名称调用方法”部分