jbock:无反射的Java命令行参数解析器

22-03-24 banq

jbock 是一个命令行解析器,它使用与JCommander 和picocli相同的注解名称。但是它不使用反射。它是一个 注释处理器 ,可在编译时生成自定义解析器。

JCommander 是一个非常小的 Java 框架,可以轻松解析命令行参数。您使用选项描述注释字段:

import com.beust.jcommander.Parameter;

public class Args {
  @Parameter
  private List<String> parameters = new ArrayList<>();

  @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity")
  private Integer verbose = 1;

  @Parameter(names = "-groups", description = "Comma-separated list of group names to be run")
  private String groups;

  @Parameter(names = "-debug", description = "Debug mode")
  private boolean debug = false;
}

然后你只需让 JCommander 解析:

class Main {
    @Parameter(names={"--length", "-l"})
    int length;
    @Parameter(names={"--pattern", "-p"})
    int pattern;

    public static void main(String ... argv) {
        Main main = new Main();
        JCommander.newBuilder()
            .addObject(main)
            .build()
            .parse(argv);
        main.run();
    }

    public void run() {
        System.out.printf("%d %d", length, pattern);
    }
}

$ java Main -l 512 --pattern 2
512 2

 

jbock是无反射命令行解析器:

@Command
abstract class DeleteCommand {

  @Option(names = {"-v", "--verbosity"},
          description = "A named option. The return type reflects optionality.")
  abstract OptionalInt verbosity();

  @Parameter(
          index = 0,
          description = {"A required positional parameter. Return type is non-optional.",
                         "Path is a standard type, so no custom converter is needed."})
  abstract Path path();

  @Parameter(
          index = 1,
          description = "An optional positional parameter.")
  abstract Optional<Path> anotherPath();

  @VarargsParameter(
          description = {"A varargs parameter. There can only be one of these.",
                         "The return type must be List."})
  abstract List<Path> morePaths();
  
  @Option(names = "--dry-run",
          description = "A nullary option, a.k.a. mode flag. Return type is boolean.")
  abstract boolean dryRun();
  
  @Option(names = "-h",
          description = "A repeatable option. Return type is List.")
  abstract List<String> headers(); 
  
  @Option(names = "--charset",
          description = "Named option with a custom converter",
          converter = CharsetConverter.class)
  abstract Optional<Charset> charset();
  
  // sample converter class
  static class CharsetConverter extends StringConverter<Charset> {
    @Override
    protected Charset convert(String token) { return StandardCharsets.UTF_8; }
  }
}



生成的DeleteCommandParser将一个字符串数组转换为DeleteCommand的一个实例:

public static void main(String[] args) {
  DeleteCommand command = new DeleteCommandParser().parseOrExit(args);
  // ...
}