Skip to content

JCommander

h908714124 edited this page Jun 21, 2021 · 86 revisions

Fields become abstract methods

This list-valued parameter from the jcommander documentation

// JCommander: repeatable option
@Parameter(names = "--host", description = "The host")
private List<String> hosts = new ArrayList<>();

would be written like this:

// jbock: repeatable option
@Option(names = "--host", description = "The host")
abstract List<String> hosts();

which makes migration easy for repeatable options. Most options however are not repeatable (multiplicity = 0..*), but optional (multiplicity = 0..1), and here jbock's behaviour might be slightly surprising at first.

Type change for optional fields

In JCommander, every option or parameter that doesn't set the required = true attribute is considered optional. Like this one:

// JCommander: optional option
@Parameter(names = { "-v", "--verbose" }, description = "Level of verbosity")
private Integer verbose = 1;

If the verbose option is not present in the input array, a default value is used. In this case, the default value is the number 1. If no such explicit default value were defined, Java's null reference would be used as a fallback.

By contrast, jbock does not assign default values to anything, except java.util.Optional and its cousins OptionalInt, OptionalLong and OptionalDouble. In particular, jbock never uses null as a default value.

Consequentially, if the option's type is Integer, jbock will treat it as a "required option" (multiplicity = 1). There isn't an attribute like JCommander's "required" to change this.

In order to make an "optional option" (multiplicity = 0..1) in jbock, the type of the option must change. OptionalInt or Optional<Integer> will work.

For example, this would be an "optional option" in jbock:

// jbock: optional option
@Parameter(names = { "-v", "--verbose" }, description = "Level of verbosity")
abstract OptionalInt verbose();

but this would be a "required option":

// jbock: required option
@Parameter(names = { "-v", "--verbose" }, description = "Level of verbosity")
abstract Integer verbose();
Note how similar jbock's required option is to the JCommander example. When migrating a non-repeatable option or parameter, ask yourself if it is required or not. Then choose the appropriate type. For a named option, the correct type will probably be Optional<Something>.

In the "required" example, if the primitive type int were to be used instead of Integer, the result would be similar. The generated parser would consider int verbose a required option. jbock does not assume a default value of 0 for an int option, just like it doesn't assume a default value of null for an Integer option.

Clone this wiki locally