Consider using covariance in generated interfaces' collections
Description
We currently generate interfaces which result in:
List<Foo> getFoo();
i.e. we are using invariant type for the returned List. This is kind of okay and is readable by novices, but has a downside - there are no compile-time guards against attempted mutation of the collection - which usually will end up blowing up at runtime.
We should consider returning covariants, such that the above becomes:
List<? extends @NonNull Foo> getFoo();
This has the benefit of allowing reads from the List, but writes are stopped cold by the compiler - you just cannot put anything into the list (unless you battle the type system and perform a raw/unchecked cast).
We currently generate interfaces which result in:
List<Foo> getFoo();
i.e. we are using invariant type for the returned List. This is kind of okay and is readable by novices, but has a downside - there are no compile-time guards against attempted mutation of the collection - which usually will end up blowing up at runtime.
We should consider returning covariants, such that the above becomes:
List<? extends @NonNull Foo> getFoo();
This has the benefit of allowing reads from the List, but writes are stopped cold by the compiler - you just cannot put anything into the list (unless you battle the type system and perform a raw/unchecked cast).