2

I'm trying to invoke a method with an unknown number of parameter (when being invoked) using reflection.

I've seen a number of similar questions here, e.g. How to invoke method with variable arguments in java using reflection? or How to invoke a method in java using reflection but these use methods names: ReflectionExample.class.getMethod("test", int.class) which is not what I'm trying to do.

Please see the sample code below:

/* an arbitary class extending a base class */
public class MyClass extends MyBaseClass {

    private String message = "";

    public void setMessage(String value){
        this.message = value;
    }

    public String getMessage(){
        return this.message;
    }

    public String method1(){
        /* blah blah */
        return getMessage();
    }
 }

/* another class extending the arbitary class */
public class MyOtherClass extends MyClass {

    public List<T extends MyClass> method2(SomeEnum enumValue, Object otherValue){
        List<MyClass> list = new ArrayList<MyClass>();
        MyClass c = new MyClass();
        c.setMessage("first message: " + enumValue.toString());
        list.add(c);
        MyClass c = new MyClass();
        c.setMessage("second message: " + otherValue.toString());
        list.add(c);
        return list;
    }

    public Object method3(Object param1, Object param2, Object param3){
        /* ... */
    }
}

/* use reflection to determine how to process the result */
public class Resolver{

  public void DoReflect(MyBaseClass obj){

     Method[] methods = obj.getMethods();

     for (Method m : methods){
       /*
        * this invoke works fine for MyClass.method1
        * but throws an exception for MyOtherClass.method2 or MyOtherClass.method3
        */

       /* many thanks to Andy Turner for his assistance.
          I've edited the original post to show his recommended solution */
       Class<?>[] klasses = m.getParameterTypes(); 
       Object[] oobjects = new Object[klasses.length]; 
       for (int x =0; x<klasses.length; x++) 
           oobjects[x] = klasses[x].newInstance(); 
       Object value = m.invoke(myclass, oobjects)

       // ... do some stuff
     }
  }
}

I would very much appreciate any help you could give me on this.

Thanks in advance.

7
  • 1
    Have you looked at the Javadoc for Method? e.g. getParameterTypes() tells you how many parameters it expects (via its length), and the types they should have. Commented Feb 8, 2016 at 14:32
  • What do you expect to happen when calling a method that requires 3 arguments with 0 arguments? Commented Feb 8, 2016 at 14:34
  • 1
    Thank you both @Andy Turner and @mhlz. So are you saying something likeClass<?> klasses = m.getParameterTypes(); Object[] oobjects = new Object[klasses.length]; for (int x =0; x<klasses.length; x++) oobjects[x] = klasses[x].newInstance(); Object value = m.invoke(myclass, oobjects); will suffice? Commented Feb 8, 2016 at 15:55
  • @GoCoding looks basically right; try it. Commented Feb 8, 2016 at 15:56
  • @AndyTurner great! much appreciated. I'll edit the original post in case someone else could use this. Commented Feb 8, 2016 at 15:59

1 Answer 1

-2
private static Object methodInvoke(Object instance, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
            return switch (method.getParameterCount()) {
                case 0 -> method.invoke(instance);
                case 1 -> method.invoke(instance, args[0]);
                case 2 -> method.invoke(instance, args[0], args[1]);
                case 3 -> method.invoke(instance, args[0], args[1], args[2]);
                default -> method.invoke(instance, args);
            };
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.