我想通过具有不同数量参数的method.invoke(clazz,varargs)使用反射来进行方法调用,并以这种方式实现仅通过一次调用而不是通过显式的硬编码数量的参数来调用不同方法。目前,我执行以下操作:
...
determine method arguments via reflection
...
if (numberOfArguments == 0) {
method.invoke(clazzInstance, null);
} else if (numberOfArguments == 1) {
method.invoke(clazzInstance, arg0);
} else if (numberOfArguments == 2) {
method.invoke(clazzInstance, arg0, arg1);
} ... etc
有没有一种方法可以更优雅地做到这一点,而无需显式检查参数数量?
答案 0 :(得分:3)
将arg0
,arg1
,argsN
收集到Object[]
数组中,将大小截断为numberOfArguments
并传递给它:
Object[] args = {arg0, arg1, ..., argsN};
method.invoke(clazzInstance, Arrays.copyOfRange(args, 0, numberOfArguments));
答案 1 :(得分:2)
varargs作为数组传递,因此您必须像下面这样创建该数组:
var args = Arrays.asList(arg1, ...).toArray()
或
var args = List.of(arg1, ...).toArray()
甚至创建一个方法,最终是您已经在编写的方法,接收可变参数
void method(Object... args) {
...
上述所有选项的调用方法都类似
method.invoke(instance, args);
这一切都取决于整个上下文
变量(几乎)被视为数组,也就是说,type... args
与方法内部的type[] args
相同,编译器仅在调用此类方法时将参数转换为数组。>
答案 2 :(得分:0)
如果您要调用的方法接受可变类型的相同类型的args,例如
method(type...arg)
您可以仅使用数组作为参数
method.invoke(clazzInstance, arg[])
如果参数的类型不同,我不建议您使用method(Object [] ... obj)之类的方法,因为您对方法必须使用的类型没有任何限制,这可能会导致代码分解时出错