How does ApplicationArguments parse option versus non-option arguments, and what do its accessor methods return?
answer
- -- prefix = option
- --name=value assigns; --name = empty list
- repeated option accumulates values
- getOptionValues null vs empty
- also bound to Environment property source
basics
~10 sTokens shaped like --name or --name=value become 'option' arguments; everything else is a 'non-option' argument. getOptionValues(name) returns a List of that option's values, getNonOptionArgs() returns the plain tokens, and getSourceArgs() returns the raw array.
solid answer
~50 sApplicationArguments splits the raw command line by a simple rule: a token starting with -- is an option (--name alone means the option is present with an empty value list; --name=value assigns a value), and any token not starting with -- is a non-option argument. Repeating an option accumulates values, so --file=a --file=b yields getOptionValues("file") == ["a", "b"]. Key methods: getOptionNames() returns the Set of option names seen; containsOption(name) tests presence; getOptionValues(name) returns a List<String> of that option's values, or null if the option was never supplied (versus an empty list when supplied with no value); getNonOptionArgs() returns the List of plain tokens; getSourceArgs() returns the untouched String[]. Under the hood Spring uses a SimpleCommandLinePropertySource-style parser, and these same --key=value options are also bound to the Environment as properties, which is why --server.port=9000 both appears here and configures the app.
code
java · 13 lines@Component
class ArgsInspector implements ApplicationRunner {
public void run(ApplicationArguments args) {
// launched: --mode=batch --file=a.csv --file=b.csv --verbose import /tmp/x
args.containsOption("verbose"); // true
args.getOptionValues("verbose"); // [] (present, no value)
args.getOptionValues("file"); // ["a.csv", "b.csv"]
args.getOptionValues("missing"); // null (never supplied)
args.getOptionNames(); // [mode, file, verbose]
args.getNonOptionArgs(); // [import, /tmp/x]
args.getSourceArgs(); // raw String[] as passed
}
}go deeper
Know option args start with -- and non-option args are the rest.
Name the core accessors and that repeated options accumulate into a list.
Explain the null-vs-empty-list contract and the link to the Environment property source.
Discuss designing CLI-driven Spring apps, disabling command-line property binding, and injecting ApplicationArguments beyond runners.
## The parsing rule `ApplicationArguments` (interface `org.springframework.boot.ApplicationArguments`, default implementation `DefaultApplicationArguments`) classifies each raw command-line token: - **Option argument** — a token that starts with `--`. Two forms: - `--name=value` → option `name` gets the value `value`. - `--name` (no `=`) → option `name` is present with an **empty** value list. - **Non-option argument** — any token that does **not** start with `--` (e.g. `import`, `/data/file.csv`, `42`). A single hyphen token like `-x` is **not** treated as an option by this parser; it falls into non-option args (Spring's option syntax requires the double dash). ## Accumulation of repeated options Option values are collected into a list. Given `--file=a.csv --file=b.csv`, `getOptionValues("file")` returns `["a.csv", "b.csv"]`. This is why the return type is `List<String>`, not a single `String`. ## The accessor methods and their exact contracts - `Set<String> getOptionNames()` — every option name that appeared. - `boolean containsOption(String name)` — whether that option was supplied at all. - `List<String> getOptionValues(String name)` — the values for that option. Returns **`null`** if the option was never present, but an **empty list** (`[]`) if the option was present with no value (e.g. bare `--seed`). This null-vs-empty distinction is a real gotcha. - `List<String> getNonOptionArgs()` — all non-option tokens, in order. - `String[] getSourceArgs()` — the original, unmodified argument array. ## Relationship to the Environment By default Spring Boot also adds these `--key=value` command-line options as a high-priority `PropertySource` (`commandLineArgs`) in the `Environment`. That is why launching with `--server.port=9000` both configures the server and shows up in `ApplicationArguments`. You can disable adding them to the Environment via `SpringApplication.setAddCommandLineProperties(false)`, but they still appear in `ApplicationArguments`. ## Injecting ApplicationArguments anywhere `ApplicationArguments` is itself a bean, so you are not limited to `ApplicationRunner` — you can constructor-inject it into any component to read parsed args later. ## Gotchas summary - Bare `--flag` gives an empty value list, not null; a missing flag gives null. Test presence with `containsOption`. - Single-dash tokens are non-options here. - Values are lists because options can repeat. - Non-option args preserve order and include things like file paths or subcommands.
- What is the difference between getOptionValues returning null versus an empty list?null means the option was never supplied on the command line; an empty list means the option was supplied in bare --name form with no value. Use containsOption for an unambiguous presence check.
- Do command-line --key=value args affect anything beyond ApplicationArguments?Yes. By default Spring adds them as a high-precedence 'commandLineArgs' PropertySource in the Environment, so --server.port=9000 also configures the app. It can be disabled with setAddCommandLineProperties(false).
saying these in an interview costs you the question
- Saying getOptionValues returns a single String
- Claiming a missing option and a valueless option both return null (or both empty)
- Treating single-dash -x as an option argument
- Not knowing command-line options also become Environment properties