Search code examples
javafunctional-programminggeneric-programming

Java how to implement interface with a variadic method and generic return type


I am trying to implement a U.I. where in the user will type a value into the console and my program is supposed to call a function which will either just execute and modify some value or execute and return something. In either case, this function could take parameters or not.

So at this point this is basically sounding like getters and setters, but I don't want to fully implement it in that fashion and this is to avoid having to go through 10+ if statements to determine what to do for any given user input.

So my solution is to create a sort of interface like this inside my class and for each activity I want to run, I create an instance of it using this interface:

private interface DoActivity <R> {
    public R execute(Object... param);
}

This works for when I don't want to specify the types of the parameters to pass to the execute method, but when I create an instance of DoActivity like this with it's execute method:

private class setPerson implements DoActivity {
    @Override
    public Void execute(String name, String telephone) {
        ...
        return null;
    }
}

I get an error with the above: method does not implement or override a method from supertype Is there a way to do what I want without resorting to reflection?

Sample use:

// at prompt
>> Enter an operation: 1 Bumble Bee
>> ...

// In program
String input = "1 Bumble Bee";
String split[] = input.split();
int operation = Integer.parseInt(split[0]);
DoActivityArray[operation - 1].execute(split[1], split[2]);

Solution

  • The solution, for your particular example, is actually quite easy:

    private class setPerson implements DoActivity{
        @Override
        public Object execute(final Object ...params){
            if(params.length != 2)
                throw new RuntimeException(
                    "setPerson must take an array of exactly two strings");
            try{
                final String name = (String)params[0];
                final String telephone = (String)params[1];
                ...
                return null;
            } catch(ClassCastException cce){
                throw new RuntimeException(
                    "setPerson must take an array of exactly two strings");
            }
        }
    }