Подтвердить что ты не робот

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

У меня есть класс 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);

Я получаю ошибку "неправильное количество аргументов". Что мне не хватает?

4b9b3361

Ответ 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});
    }
}