Неправильное количество аргументов при вызове метода
У меня есть класс AClass
и метод someMethod
, который получает в качестве параметра массив Object
.
public class AClass {
public void someMethod(Object[] parameters) {
}
}
В основном, когда я пытаюсь вызвать этот метод для объекта, который я создал, и предоставить массив объектов в качестве параметра для этого метода
Object[] parameters; // lets say this object array is null
Class class = Class.forName("AClass");
Object anObject = class.newInstance();
Method someMethod = class.getDeclaredMethod("someMethod", parameters.getClass());
someMethod.invoke(anObject, parameters);
Я получаю ошибку "неправильное количество аргументов".
Что мне не хватает?
Ответы
Ответ 1
Все будет в порядке.
Object[] parameters ={new Object()}; // lets say this object array is null
Class clas = Class.forName("AClass");
Object anObject = clas.newInstance();
Object[] param ={parameters};
Method someMethod = clas.getDeclaredMethod("someMethod", parameters.getClass());
someMethod.invoke(anObject, param);
Будьте осторожны со вторым параметром метода invoke. Сам объект Object [], и тип аргумента вашего метода также является Object [].
Ответ 2
Чтобы немного рассказать о том, что говорят Орион и Бяобяоци. , ,
Вероятно, вас здесь смущает то, что Method.invoke(Object, Object...)
обычно может просто принимать аргументы, так сказать, "inline"; когда компилятор видит что-то вроде someMethod.invoke(someObject, arg1, arg2)
, он неявно создает массив new Object[]{arg1, arg2}
и затем передает этот массив в Method.invoke
. Method.invoke
передает элементы этого массива в качестве аргументов Method.invoke
методу. Все идет нормально.
Но когда компилятор видит что-то вроде someMethod.invoke(someObject, someArray)
, он предполагает, что вы уже упаковали аргументы в массив; поэтому он не будет переупаковывать их снова. Затем Method.invoke
попытается передать элементы someArray
качестве аргументов someArray
методу, а не передавать сам someArray
в качестве аргумента.
(Это всегда, как работает нотация ...
; она принимает либо массив, содержащий элементы соответствующего типа, либо ноль или более аргументов соответствующего типа.)
Таким образом, как сказали Ori и Biaobiaoqi, вам нужно перевернуть ваши parameters
в дополнительный массив, new Object[] {parameters}
, чтобы сами parameters
конечном итоге передавались в ваш метод.
Имеет ли это смысл?
Ответ 3
Метод Method.invoke принимает объект для получения вызова метода и массива аргументов метода. Поскольку ваш метод принимает один аргумент, заданный массив должен иметь размер один.
попробуйте создать новый массив размером 1:
someMethod.invoke(anObject, new Object[] {parameters});
Обратите внимание, что одно значение в этом массиве может быть нулевым. Это будет имитировать anObject.someMethod(null)
Ответ 4
Параметры invoke
- это массив Object
; ваши параметры должны быть Object[]
, содержащие Object[]
, которые вы передаете someMethod
.
Вам не нужно создавать немедленный массив для этого, так как подпись invoke
invoke(Object, Object...)
, но в вашем случае вы пытаетесь передать пустой массив. Если вы хотите передать null:
Object[] parameters = { null };
...
someMethod.invoke(anObject, parameters);
В конечном счете, однако, другие ответы верны: вам нужно передать Object[]
, содержащий запись для каждого из параметров методов.
Ответ 5
попробуйте следующее:
someMethod.invoke(anObject, new .java.lang.Object[1][]{parameters});
Я получил автоматическое создание версии API Reflection вашего кода с помощью dp4j:
$ javac -cp dp4j-1.2-jar-with-dependencies.jar -Averbose=true AClass.java
AClass.java:10: Note:
import com.dp4j.*;
public class AClass {
public AClass() {
super();
}
public void someMethod(Object[] parameters) {
}
@Reflect(all = true)
public static void main(String... args) throws ... {
Object[] parameters = null;
...
AClass anObject;
anObject = (.AClass)aClassConstructor.newInstance();
java.lang.reflect.Method someMethodWithArrayMethod = null;
someMethodWithArrayMethod = Class.forName("AClass").getDeclaredMethod("someMethod", .java.lang.Object[].class);
someMethodWithArrayMethod.setAccessible(true);
someMethodWithArrayMethod.invoke(anObject, new .java.lang.Object[1][]{parameters});
}
}