Question

I have class AClass and a method someMethod that gets an Object array as parameter.

public class AClass {
    public void someMethod(Object[] parameters) {
    }
}

In main, when I try to invoke this method on the the object that I have created and give an object array as a parameter to this method

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);

I get "wrong number of arguments error". What am i missing?

Was it helpful?

Solution

That will be all right.

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);

Be careful about the second parameter of the invoke method. It's Object[] itself, and the argument type of your method is Object[] too.

OTHER TIPS

To expand a bit on what orien and biaobiaoqi are saying . . .

What's probably confusing you here is that Method.invoke(Object, Object...) can usually just take the arguments "inline", so to speak; when the compiler sees something like someMethod.invoke(someObject, arg1, arg2), it implicitly creates an array new Object[]{arg1, arg2} and then passes that array to Method.invoke. Method.invoke then passes the elements of that array as arguments to the method you're invoking. So far, so good.

But when the compiler sees something like someMethod.invoke(someObject, someArray), it assumes that you've already packaged the arguments into an array; so it won't repackage them again. So then Method.invoke will try to pass the elements of someArray as arguments to the method you're invoking, rather than passing someArray itself as an argument.

(This is always how the ... notation works; it accepts either an array containing elements of the appropriate type, or zero or more arguments of the appropriate type.)

So, as orien and biaobiaoqi have said, you need to rewrap your parameters into an additional array, new Object[] {parameters}, so that parameters itself ends up being passed into your method.

Does that make sense?

The Method.invoke method takes the object to receive the method call and an array of the arguments to the method. As your method takes one argument, the array given must have a size of 1.

try creating a new array with size 1:

someMethod.invoke(anObject, new Object[] {parameters});

Note that the one value in this array can be null. This would simulate anObject.someMethod(null)

The parameters to invoke is an array of Object; your parameters should be an Object[] containing the Object[] you're passing to someMethod.

You don't need to create an immediate array to do this, since the invoke signature is invoke(Object, Object...), but in your case you're trying to pass in an empty array. If you want to pass in null:

Object[] parameters = { null };
...
someMethod.invoke(anObject, parameters);

Ultimately, however, the other answers are correct: you need to pass in an Object[] containing an entry for each of the methods parameters.

try this:

    someMethod.invoke(anObject, new .java.lang.Object[1][]{parameters});

I got by automatically-generating a Reflection API version of your code with 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});
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top