java.reflection: Как я могу сделать method.invoke (clazz, varargs) с динамическим числом аргументов? - PullRequest
0 голосов
/ 09 октября 2018

Я хочу делать вызовы методов, используя отражение через 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

Есть ли способ сделать это более элегантно без необходимости явной проверки количества аргументов?

Ответы [ 3 ]

0 голосов
/ 09 октября 2018

если метод, который вы вызываете, принимает переменное количество аргументов одного типа, например

method(type...arg)

, вы можете просто использовать массив в качестве параметра

method.invoke(clazzInstance, arg[])

Еслиаргументы имеют различный тип, я не советую вам делать метод, подобный методу (Object [] ... obj), потому что вы не накладываете никаких ограничений на типы, с которыми должен работать метод, и это может привести ккакая-то ошибка при разработке кода

0 голосов
/ 09 октября 2018

varargs передаются в виде массива, поэтому вы должны создать этот массив как в:

var args = Arrays.asList(arg1, ...).toArray()

или

var args = List.of(arg1, ...).toArray()

или даже создать метод, в конце концов тот, который вы уже используетезапись, получение переменных varargs

void method(Object... args) {
    ...

Все вышеперечисленные опции, в которых вызывается метод, например

method.invoke(instance, args);

все зависит от всего контекста

Varargs (почти) обрабатываются как массивы, то есть type... args - это то же самое, что и type[] args внутри метода, компилятор просто преобразовывает аргументы в массив при вызове такого метода.

0 голосов
/ 09 октября 2018

Соберите arg0, arg1, argsN в массив Object[], обрежьте размер до numberOfArguments и передайте его:

Object[] args = {arg0, arg1, ..., argsN};
method.invoke(clazzInstance, Arrays.copyOfRange(args, 0, numberOfArguments));
...