How does @ShellOption control option names, defaults, required-ness, and arity for command parameters?
answer
- No defaultValue => required option
- ShellOption.NULL_DEFAULT sentinel for null
- arity 0 = boolean flag
- arity >1 / collection = multiple values
- value = the --names; needs -parameters otherwise
basics
~10 s@ShellOption customizes a command parameter: it sets the option name(s), a defaultValue (which also makes it optional), help text, and arity (how many values it consumes). Without a default, a parameter is required.
solid answer
~40 s@ShellOption is a parameter-level annotation that configures how a method parameter is exposed as a command option. Its `value` sets one or more long names (e.g. `--role`); if omitted the parameter name is used (needs `-parameters`). `defaultValue` supplies a value when the user omits the option — and crucially, providing a default is what makes the parameter optional; without one, the option is required and a missing value is an error. Use the sentinel `ShellOption.NULL_DEFAULT` to default to null. `arity` controls how many tokens the option consumes: default 1, `0` for boolean flags (presence = true), and higher for collecting several values into an array/List. `help` is per-option documentation, and `valueProvider` wires tab-completion. Options can be passed positionally or with `--name value`.
code
java · 10 lines@ShellMethod(key = "deploy", value = "Deploy a service")
public String deploy(
@ShellOption(value = "--service", help = "Service name") String service,
@ShellOption(value = "--replicas", defaultValue = "1") int replicas, // optional
@ShellOption(value = "--force", arity = 0) boolean force, // flag
@ShellOption(value = "--tags", arity = 2, defaultValue = ShellOption.NULL_DEFAULT)
String[] tags) { // multi-value
return "deploy " + service + " x" + replicas + (force ? " (forced)" : "");
}
// shell:> deploy --service api --replicas 3 --force --tags blue canarygo deeper
Knows @ShellOption sets the name and a default value.
Understands required-by-default, defaultValue, NULL_DEFAULT, and basic arity for flags.
Explains multi-value binding, ConversionService type coercion, and valueProvider completion.
Designs consistent option grammars and completion UX across a command suite; considers backward-compatible option evolution.
**Purpose.** `@ShellOption` is placed on a *parameter* of a `@ShellMethod` and controls how that parameter appears and behaves as a command-line option. **Naming — the `value` attribute.** It is a `String[]`; you can supply one or more names such as `@ShellOption({"--role", "-r"})`. If you omit `value`, the option name is taken from the parameter name, which requires compilation with `-parameters` (otherwise it becomes `arg0`, etc.). The `prefix` (default `--`) is set on `@ShellMethod`. **Required vs optional — `defaultValue`.** By default every command parameter is **required**: if the user does not supply it, the command errors. Supplying `defaultValue = "..."` makes the option optional and injects that value when absent. To default to `null`, use the sentinel constant `ShellOption.NULL_DEFAULT` (you cannot write a literal null in an annotation). There is a related sentinel `ShellOption.NONE` used internally to mean "no default configured." **Arity — how many tokens are consumed.** - Default `arity = 1`: consumes exactly one value (`--role ADMIN`). - `arity = 0`: a boolean flag. The parameter type is typically `boolean`; presence of `--force` yields `true`, absence yields `false`. Boolean options infer arity 0 automatically. - `arity > 1` or a collection/array parameter: consumes multiple tokens (`--tags a b c`), binding into `String[]`, `List<String>`, etc. **Positional vs named.** Users can pass options by name (`--role ADMIN`) or positionally in declaration order (`add-user alice ADMIN`). Named options can appear in any order. **Type conversion.** Spring's `ConversionService` converts string tokens to the parameter type (int, enum, LocalDate, custom types via registered converters). Invalid input yields a conversion error. **help and valueProvider.** `help` documents the option in `help <command>`. `valueProvider` names a `ValueProvider` bean/class that supplies tab-completion candidates. **Gotchas.** - Forgetting a default on an option you intended to be optional makes it mandatory — a common source of "why does it demand this argument?". - `-parameters` must be enabled to rely on parameter names. - Boolean flags default to arity 0; don't give them a value on the command line. - `defaultValue` is a `String`; it is converted to the parameter type just like user input, so it must be parseable (e.g. `defaultValue = "0"` for an int). **When to use.** Any time you need friendlier option names, optional arguments, flags, multi-valued inputs, or completion — which is nearly every real command.
- How do you make a String option default to null?Use defaultValue = ShellOption.NULL_DEFAULT — a sentinel constant, because annotation attributes can't hold a literal null. Absence of the option then injects null instead of erroring.
- What is the difference between arity 0 and arity 1?Arity 0 is a boolean flag whose presence alone means true and consumes no value token; arity 1 consumes exactly one following token as the option's value.
saying these in an interview costs you the question
- Saying parameters are optional by default (they are required unless given a defaultValue)
- Passing a value to an arity-0 boolean flag
- Trying to use null literally in defaultValue instead of ShellOption.NULL_DEFAULT
- Assuming option names work without the -parameters compiler flag