Java反射:根据参数和签名自动调用正确的重载方法

时间:2017-08-09 07:37:26

标签: java reflection overloading

假设有一个名为doTask的重载方法:

public class Game {
  void doTask(Joker joker);
  void doTask(Batman batman, Robin robin);
}

我想调用正确的方法,给定方法的名称("doTask")和参数数组,其数量和类型不是先验的。

通常,这至少涉及三个步骤:
1.找到参数的数量及其类型,并创建一个数组Class[] myTypes 2.确定正确的重载Method,即Method rightMethod = game.getClass().getMethod("doTask", myTypes);
3.调用方法:rightMethod.invoke(paramArray)

是否存在要求Java反射自动识别要使用的正确重载方法的工具,并使我们不必执行步骤1和步骤2?我理想地想,这就像: Library.invoke("doTask", paramArray);

2 个答案:

答案 0 :(得分:5)

有这样的设施,java.beans.Statement,resp。 Expression如果需要返回值:

Game game = new Game();
Joker joker = new Joker();
Statement st = new Statement(game, "doTask", new Object[]{ joker });
st.execute();

但是,它仅适用于public方法。

此外,与java.lang.reflect.Method不同,此工具尚未适用于支持 varargs 参数,因此您必须手动创建参数数组。

可以证明,它根据参数类型选择正确的目标方法,而不一定与参数类型相同:

ExecutorService es = Executors.newSingleThreadExecutor();
class Foo implements Callable<String> {
    public String call() throws Exception {
        return "success";
    }
}
// has to choose between submit(Callable) and submit(Runnable)
// given a Foo instance
Expression ex = new Expression(es, "submit", new Object[]{ new Foo() });
Future<?> f = (Future<?>)ex.getValue();
System.out.println(f.get());
es.shutdown();

答案 1 :(得分:1)

首先 - 回答你的问题 - 不,没有这样的设施。

其次,第2步有点复杂,因为从参数创建类数组并调用getMethod并不足够。

实际上,您必须遍历所有与名称,参数数量匹配的方法,并比较给定参数类型(即methodArgType.isAssignableFrom(paramType))的赋值兼容性方法的参数类型,以确保兼容的子类型方法参数类型的正确反映。 varargs会让事情变得更加复杂。