Picocli: Set optional parameters to empty container if type is array or collection

Created on 12 Feb 2018  路  6Comments  路  Source: remkop/picocli

Hi there,

I recently had the following situation:

@Parameters(arity = "0..*", description = "tbd") private Set<Type> someParams;

If I do not specify any params at command line, someParams is null which is a bit surprising / annoying when it comes to working with arrays / collections.

The Documentation says:

If the field is null, picocli will instantiate it.

Which does not seem to be the case if no params are specified.

Is this the default picocli behavior? Do I miss something?

I would like picocli to create an empty array / collection in this case. This helps to keep the code simple and comprehensible as checking for null on container members is odd and causes boiler plate.

Thank you very much for any input on this.

doc question

All 6 comments

You are correct that this is the current behaviour: fields are only instantiated if picocli finds a matching argument on the command line.

For single-value fields, this allows applications to detect which options and parameters were specified on the command line, and which ones were not. For consistency I kept the same behaviour with multi-value fields (arrays and collections).

Overall, picocli can be improved in the area of assigning default values. I recently started thinking about this more after discussion in issue #261. It seems to me that your request falls into the category of "picocli needs better defaulting", so is related to #261. I can easily imagine a IDefaultValueProvider implementation that instantiates multi-value fields...

Question though, if the main concern is avoiding null-checking, why not simply instantiate the field with the declaration, like this:

@Parameters(arity = "0..*", description = "tbd")
private Set<Type> someParams = new LinkedHashSet<>();

I didn't know that this was possible because I do not know when picocli is going to set the command's members. So, I understand that I could specify "default values" directly as plain old Java member initializer? Picocli will not touch them if it finds no match? This would be acceptable for me (may be a good point to include into the documentation though).

FYI: My whole point is somewhat influenced by Josh Bloch's Effective Java Item 54: Return empty collections or arrays, not nulls.

Yes, that is correct. Field initializers are currently the only way to provide default values.
(For arrays and collections, there is one "gotcha": if you specify a non-null array or collection, picocli will _add_ values to this array or collection. Existing values are not replaced at the moment. This makes it impossible to specify a default other than an empty array or collection... There is an outstanding request to improve this: #216)

Thanks for pointing out that the documentation for this can be improved, I'll take a look!

I like! Thx for the quick answers.

Glad to hear that solved the issue. Are you okay to close this ticket?

The user manual has been updated with better docs for the 2.3 release.

Was this page helpful?
0 / 5 - 0 ratings