user1948008
user1948008

Reputation: 21

Method.invoke throws java.lang.IllegalArgumentException: wrong number of arguments

public class ReflectionTest {
 public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException  {
            // TODO Auto-generated method stub
            ReflectionTest t = new ReflectionTest();
            Method method[]= t.getClass().getMethods();
            System.out.println(method.length);
            for(int i=0;i<=method.length;i++){
                method[i].invoke(t);
            }
        }
            public void abc(){
                System.out.println("abc");
            }
            public void xyz(){
                System.out.println("XYZ");
            }
    }

Result shows:

abc
xyz
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.selenium.test.ReflectionTest.main(ReflectionTest.java:21)

Please help me how to handle this

Upvotes: 2

Views: 4077

Answers (5)

Elliott Frisch
Elliott Frisch

Reputation: 201507

If I understand your question, you need to skip invoking main (since it requires a String[] args) and other method(s) of Object, that is

ReflectionTest t = new ReflectionTest();
Method method[] = t.getClass().getMethods();
System.out.println(method.length);
for (int i = 0; i < method.length; i++) {
  if (method[i].getName().equals("abc") || method[i].getName().equals("xyz")) {
    try {
      method[i].invoke(t, null);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

seems to work correctly here.

Upvotes: 1

Dawnkeeper
Dawnkeeper

Reputation: 2875

The error occurs when you try to call a method that needs parameters without supplying any.

For a general solution you might want to test this:

if (method[i].getParameterTypes().length ==0)
{
   method[i].invoke(t);
}

This tests if the method has parameters and skips it

See here

Upvotes: 0

AlexR
AlexR

Reputation: 115378

Think again what are you doing. You iterate over all public methods available in your class (including methods declared in super class) and try to invoke without arguments, i.e. assume that all methods do not accept any argument that is definitely wrong. For example equals(Object) or wait(long) inherited from java.lang.Object require one argument.

EDIT

The same is about your own method main(String[]).

Occasionally getMethods() returns first 2 methods that do not require arguments: abc() and xyz() that are invoked successfully. Then the turn of main() arrives and you fail. But even if you add some if() statement to ignore main you will fail on one of methods inherited from Object that I have already mentioned.

If you want to try only methods declared in your class use getDeclaredMethods() instead of getMethods().

Upvotes: 0

vinayknl
vinayknl

Reputation: 1252

The error is because along with abc() and xyz(), you have lot of other methods present.

equals
hashCode
toString
abc
xyz
getClass
notify
notifyAll
wait

You can use below logic if you want to run your methods

for(int i=0;i<method.length;i++){

    if(method[i].getName().equals("abc") || method[i].getName().equals("xyz"))
    {
        method[i].invoke(t);
    }

}

Upvotes: 3

Baalthasarr
Baalthasarr

Reputation: 367

the problem is in

for(int i=0;i<=method.length;i++){
            method[i].invoke(t);
}

you iterate until i has the same value like method.length. Because an array start with 0 and the method.length count from 1.

You have to iterate until i<method.length OR i<=method.length-1

For example.

method[] has one item.

method[0] <- first and only item
method.length <- will return 1 becuase there is only one item.

You can say:

method[method.length-1] <- this will be the last item.

Upvotes: 0

Related Questions