skip to content

How does ApplicationArguments parse option versus non-option arguments, and what do its accessor methods return?

level: seniorimportance: should knowfreq 45%

answer

  1. -- prefix = option
  2. --name=value assigns; --name = empty list
  3. repeated option accumulates values
  4. getOptionValues null vs empty
  5. also bound to Environment property source

basics

~10 s

Tokens 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 s

ApplicationArguments 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
java
@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

for a junior

Know option args start with -- and non-option args are the rest.

for a middle

Name the core accessors and that repeated options accumulate into a list.

for a senior

Explain the null-vs-empty-list contract and the link to the Environment property source.

for a principal

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

context