Java Generics: Producer Extends Consumer Super

I do quite a lot of Java as part of the work I do at Gojek and one of the most helpful, but at times confusing part of the language is generics. Here I will be mentioning an interesting concept I recently came across — PECS or “Producer Extends, Consumer Super”

Photo by Samuel Sianipar on Unsplash

Generics in Java are invariant by default and are applied at compile-time. Polymorphic type arguments do not imply polymorphism in generic types, i.e., You cannot assign List<String> to List<CharSequence>.

However, with extends and super, you achieve “covariance” and “contra-variance” that aids in designing type-safe generic code aware of inheritance and polymorphism.

This is useful in defining methods that accept collection types.

Examples

? extends T — covariance

You need to apply a List<Rule> over a StateMachine instance Here the List<Rule> is a “producer.”

interface Rule {void apply(StateMachine m);}class FireWallRule implements Rule {// ...}class StateMachine {
// ...
public void apply(List<? extends Rule> rules) {
// ...
}
}
class Main {
public static void main(String[] args) {
var m = new StateMachine();
var rules = List.of(
new FireWallRule(),
// ...
);
m.apply(rules);
}
}

This allows you to pass a List of any objects which are implementations of Rule

? super T — contra-variance

You need to store some instances of FetchResult, a sub-type of Result into a List. Here the List is a “consumer.”

interface Result {
// ...
}
interface FetchResult extends Result {
// ...
}
class Fetcher {
putResult(List<? super FetchResult> output) {
// ...
}
}
class Main {
public static void main(String[] args) {
var result = new ArrayList<Result>();
var fetcher = new Fetcher();
// ...
fetcher.getResult(result);
}
}

This allows to pass any List that can store a FetchResult.

However, such code wont work:

List<? extends CharSequence> list = new ArrayList<>();// ...list.add("hello world"); // error here, cannot add

However, a normal List<CharSequence> will allow it.

Computer Whisperer. Open-source contributor. Find me at https://amitosh.in/

Computer Whisperer. Open-source contributor. Find me at https://amitosh.in/