Парсер командной строки Apache - PullRequest
0 голосов
/ 14 февраля 2019

Я получил приведенный ниже код из примера кода из учебника и немного его подправил.

App.java

public static void main(String[] args) throws ParseException {
        CommandTest t = new CommandTest();
        t.start(args);
}

CommandTest.java

public class CommandTest {

    void start(String[] args) throws ParseException {

          //***Definition Stage***
          // create Options object
          Options options = new Options();

          // add option "-a"
          options.addOption(
                    Option.builder("a")
                        .longOpt("add")
                        .desc("add numbers")
                        .hasArg(false)
                        .valueSeparator('=')
                        .required(false)
                        .build()
                  );

          // add option "-m"
          options.addOption("m", false, "");
          options.addOption(
                    Option.builder("m")
                        .longOpt("multiply")
                        .desc("multiply numbers")
                        .hasArg(false)
                        .valueSeparator('=')
                        .required(false)
                        .build()
                  );

          //***Parsing Stage***
          //Create a parser
          CommandLineParser parser = new DefaultParser();

          //parse the options passed as command line arguments
          CommandLine cmd = parser.parse( options, args);

          //***Interrogation Stage***
          //hasOptions checks if option is present or not
          if(cmd.hasOption("a")) { 
             System.out.println("Sum of the numbers: " + getSum(args));
          } else if(cmd.hasOption("m")) {
             System.out.println("Multiplication of the numbers: " + getMultiplication(args));
          }
       }

       public static int getSum(String[] args) {
          int sum = 0;
          for(int i = 1; i < args.length ; i++) {
             sum += Integer.parseInt(args[i]);
          } 
          return sum;
       }

       public static int getMultiplication(String[] args) {
          int multiplication = 1;
          for(int i = 1; i < args.length ; i++) {
             multiplication *= Integer.parseInt(args[i]);
          } 
          return multiplication;
       }
}

Теперь мой вопрос: когдая пытаюсь выполнить приведенный выше код с параметром -multi, он все еще будет принят?Я уже установил параметры для получения только -m или -multiply.Тем не менее, он по-прежнему будет принимать -multi

Я использую commons-cli-1.3.1 (кстати, я пытаюсь отладить унаследованный код)

Примечание. Над источником указан ОБРАЗЕЦтолько источник, не нужно применять действующие правила кодирования (хорошие или плохие), я просто хочу знать, почему поведение происходит так, как оно есть.

1 Ответ

0 голосов
/ 14 февраля 2019

Это поведение при обнаружении несоответствующей опции ( org.apache.commons.cli.Options: 233 ):

public List<String> getMatchingOptions(String opt) {
  opt = Util.stripLeadingHyphens(opt);
  List<String> matchingOpts = new ArrayList();
  if (this.longOpts.keySet().contains(opt)) {
    return Collections.singletonList(opt);
  } else {
    Iterator var3 = this.longOpts.keySet().iterator();

    while(var3.hasNext()) {
      String longOpt = (String)var3.next();
      /******************************************************/
      /* longOpt = "multiply"                               */
      /* opt = "multi"                                      */
      /******************************************************/
      if (longOpt.startsWith(opt)) {
        matchingOpts.add(longOpt);
      }
      /******************************************************/
    }

    return matchingOpts;
  }
}

Как вы можете видеть ввыделенный блок, если короткая опция не соответствует, библиотека ищет первую длинную опцию, которая частично соответствует введенной опции.Он использует startsWith, а поскольку "multiply".startsWith("multi") равен true, по умолчанию используется опция --multiply.

...