Вызов метода из пользовательского ввода в JAVA - PullRequest
0 голосов
/ 06 сентября 2018

Я ищу способ вызова любого данного метода в моем классе без необходимости выполнения всего оператора try-catch.

Пример:

public void Worker(String handle) throws Exception
{
    if(PROTOCOL.contains(handle)) 
    {
        System.out.println("good");
        Worker.handle;
    }
    else { 
            throw new Exception("Don't understand <" + handle + ">");
         }
}

PROTOCOL - список разрешенных команд.

Я знаю, что могу сказать if(input = ....){do....}, но я хочу быть в состоянии сделать выше; вызовите мой класс с входным значением.

Возможно ли это?

Ответы [ 3 ]

0 голосов
/ 06 сентября 2018

В зависимости от того, как будут выглядеть ваши команды, вы можете использовать Map<String, Command>, который затем будете использовать следующим образом:

Map<String, Command> PROTOCOL = ... //you build that map somehow

Command c = PROTOCOL.get(handle);
if( c != null ) {
    System.out.println("good");
    c.execute();
} else { 
    throw new Exception("Don't understand <" + handle + ">");
}

Command может быть интерфейсом класса или функции:

interface Command {
  void execute();
}

Используется как интерфейс класса

class MyCommand implements Command {
  //this can have private data

  void execute() {
    //do whatever is needed
  }
}

PROTOCOL.put("mycommand", new MyCommand(/*you could pass parameters here*/));

Преимущества:

  • Интерфейс может иметь более 1 метода, например он также может иметь String getName().
  • Команды могут иметь параметры, например, Вы можете предоставить одну реализацию и использовать разные имена, которые связаны с одной и той же командой с разными параметрами (например, «приращение» и «уменьшение» могут быть привязаны к AddCommand(1) и AddCommand(-1)).
  • Вы можете использовать некоторый механизм инверсии зависимостей (например, через CDI), чтобы команды регистрировались в PROTOCOL. Таким образом, вы даже можете добавлять команды через какой-то механизм плагинов.
  • Использование интерфейсов для классов может быть проще для понимания другими.
  • Легче структурировать для больших команд, так как вы можете легко извлечь классы в отдельные файлы.

Используется как интерфейс функции (например, через лямбды)

PROTOCOL.put("mycommand", () -> { 
  //do whatever is needed
});

Преимущества:

  • Не нужны классы, которые могут быть более краткими для коротких команд.
0 голосов
/ 06 сентября 2018

Вот простой рабочий пример, показывающий некоторые вещи, которые вы можете сделать, используя отражение .

Примечание: я решил сохранить доступные методы в списке, но это можно легко изменить, чтобы использовать предопределенный список строк. Я также выдал непроверенную исключительную ситуацию IllegalArgumentException из рабочего метода.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Worker {

    public void method1() {
        System.out.println("method1 called");
    }

    public void method2() {
        System.out.println("method2 called");
    }

    public void worker(String handle) throws IllegalArgumentException {
        Class<? extends Worker> clazz = this.getClass();
        List<Method> methods = Arrays.asList(clazz.getMethods());

        if (methods.stream().map(m -> m.getName()).collect(Collectors.toList()).contains(handle)) {
            try {
                Method method = clazz.getDeclaredMethod(handle);
                method.invoke(this);
            } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            throw new IllegalArgumentException("Don't understand <" + handle + ">");
        }
    }

    public static void main(String[] args) {
        new Worker().worker("method1");
        new Worker().worker("method2");
        new Worker().worker("method3");
    }
}
0 голосов
/ 06 сентября 2018

Если вы не хотите использовать try-catch (обрабатывать исключения самостоятельно), объявите эти исключения в вызывающем методе, который следует после ключевого слова throws.

https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html

По сути, вы делегируете обработку исключений вызывающей стороне вашего метода.

...