通过动态参数反射调用方法

时间:2018-05-07 08:50:05

标签: java reflection

我正在使用method.invoke(instance, args...)方式调用Class实例的某个方法,但对于instance中的每个方法,正如invoke Javadoc正确指出的那样,每个参数都必须手动指定

考虑Spring ...在HTTP调用期间如何在控制器方法中对参数进行定值? (但我确实以完全不同的方式做到了......)

我想知道Java中是否有任何方法可以动态地传递反射中的参数(或者甚至不反射),而不是单独指定每个参数。

修改

实例类声明类似于:

public class Something {

    public void doSth(String par1, String par2, Integer par3) {
        //....
    }

    public void doSthElse(String par1, Boolean par2) {
        //....
    }

    public void doSthElseMore(Integer par1) {
        //....
    }

}

我如何调用每种方法:

...
for (Method method : instance.getDeclaredMethods()) {
    Object[] array = //BL: build array of values to pass to the invoke method.
//1. doSth may be new Object[] {"abc", "def", 123}
//2. doSthElse iteration may be new Object[] {"abc", false}
//3. doSthElseMore iteration may be new Object[] {123}
    return method.invoke(instance, array);
}
...

如上所示,Something类(instance)内的每个方法都有不同数量的参数。

在每次迭代中,array都有不同数量的值传递给invoke

2 个答案:

答案 0 :(得分:3)

实际上,正如@Boris所说,我完成工作所需要做的就是将每个参数转换为正确的类型。通过这种方式,Java设法使用正确的参数类型调用Something类的正确方法。

我的项目是使用Vert.xVavr的{​​{1}}应用程序,但最后一个返回语句显示了我是如何设法解决的。

jodd

但是,可以在GitHub

上找到此项目

答案 1 :(得分:0)

由于我发现您使用的是Integer而不是int(因此示例中没有基元参数),因此您可以null向所有方法发送public static Object[] getParametersArray(Parameter[] param){ Object[] array = new Object[param.length]; // create default primitive values based on param[#].getType() return array; } 而不会出现任何问题。

因此,您可以创建一个正确长度的数组,这将适用于您的情况。

Labo l = new Labo();
for(Method m : Labo.class.getDeclaredMethods()){
    if((m.getModifiers() & Modifier.STATIC) > 0){
        System.out.println("SKIP " + m.getName());
        continue;
    }
    try {
        m.invoke(l, getParametersArray(m.getParameters()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

然后,您所要做的就是迭代该方法:

main

注意跳过的静态方法,主要是因为如果在包含public void test(String s){ System.out.println("test String " + s); } public void test2(String s1, String s2){ System.out.println("test String " + s1 + " | String " + s2); } public void test(Integer s){ System.out.println("test Integer " + s); } 方法的方法中运行它,则会进行递归调用。

用以下方法测试:

onChildAdded()
  

SKIP主要   test String null
  test整数null
  SKIP getParametersArray
  test String null | String null

注意:如果需要管理一些原始值,则需要获取参数类型以提供默认值而不是null