0

I wanted to know if there's a way in Java to put the entire method call, with the parameters, into a variable and then just call something like variable.call() to actually call it. It should work for any number of parameters. For example:

class MyClass{
    int method1(int a, int b){
        return a*b;
    }
    int method2(int a, int b, int c){
        return a*b*c;
    }
    int main(){
        int a=1,b=2;
        var call1=createCall("method1",a,b), call2=createCall("method2",a,b,c);
        return call1.call()+call2.call();
    }
}

I referenced this, but this requires for me to define the call-structure for the different calls because of the change in either type or number of parameters.

vaanchit kaul
  • 17
  • 1
  • 8

2 Answers2

2

Use lambdas:

Supplier<Integer> call1 = () -> method1(a,b);
Supplier<Integer> call2 = () -> method2(a,b,c);

Then later:

return call1.get() + call2.get();
Bohemian
  • 412,405
  • 93
  • 575
  • 722
0

Somehow we need to check how many arguments and then split the parameter before sending it to invoke method as I did in methodInvoke.

Main class

public static void main(String[] args) {
        try {
            Class clazz = DummyClass.class;
            //If I want run all methods in the same instance
            Object instance = clazz.newInstance();
            // this method is void
            CreateCall.call(clazz, instance, "setObject", new Object[]{1, 2});
            System.out.println("a : " + CreateCall.call(clazz, instance, "getA"));
            System.out.println("b : " + CreateCall.call(clazz, instance, "getB"));
            System.out.println(" a + b :" + CreateCall.call(clazz, instance, "sum"));
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

CreateCall class

class CreateCall {
    public static Object call(Class clazz, Object instance, String methodName, Object... args) throws InstantiationException, IllegalAccessException, InvocationTargetException {
        Object result = null;
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName))
                result = methodInvoke(instance, method, args);
        }
        return result;
    }

    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);
        };
    }
}
ARNR
  • 43
  • 4