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.
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);
Use the first checkbox to ignore invariant classes.
Invariant classes (e.g. java.util.List<T>
) are
classes that both accept values (via its List.add(T)
method)
and produce values (via its T List.get()
method). On the
other hand, contravariant classes only receive values, e.g. java.util.function.Consumer<T>
with the only method accept(T)
, and covariant classes
only produce values, e.g. java.util.function.Supplier<T>
with the only method T get()
. People
are often OK with bounded wildcards in covariant/contravariant
classes but afraid of wildcards in invariant classes, e.g. void
process(List<? extends T> l)
. Turn this setting off to ignore
these invariant classes and leave them rigidly typed, e.g. void
process(List<T> l)
.
Uncheck the second checkbox to ignore private methods, which can be considered as not a part of the public API.
Uncheck the third checkbox to ignore instance methods and only report static methods.