Example:
void process(Consumer<Number> consumer);
should be replaced with:
void process(Consumer<? super Number> consumer);
This method signature is more flexible because it accepts more types: not only
Consumer<Number>
, but also Consumer<Object>
.
Likewise, type parameters in covariant position:
T produce(Producer<T> p);
should be replaced with:
T produce(Producer<? extends T> p);
To quote Joshua Bloch in Effective Java third Edition:
Item 31: Use bounded wildcards to increase API flexibility
Using wildcard types in your APIs, while tricky, makes the APIs far more flexible. If you write a library that will be widely used, the proper use of wildcard types should be considered mandatory. Remember the basic rule: producer-extends, consumer-super (PECS). Also remember that all Comparables and Comparators are consumers.
Use the inspection options to toggle the reporting for:
invariant classes. An example of an invariant class is java.util.List<T>
because it both accepts values
(via the List.add(T)
method)
and produces values (via the T List.get()
method).
On the
other hand, contravariant
classes only receive values, for example, java.util.function.Consumer<T>
with the only method accept(T)
. Similarly, covariant
classes
only produce values, for example, java.util.function.Supplier<T>
with the only method T get()
.
People often use bounded wildcards in covariant/contravariant
classes but avoid wildcards in invariant classes, for example, void process(List<? extends T> l)
.
Disable this option to ignore such invariant classes and leave them rigidly typed, for example, void
process(List<T> l)
.
private
methods, which can be considered as not a part of the public API
instance methods