Search code examples
javagenericsinheritancesuper

What is a real life example of generic <? super T>?


I understand that <? super T> represents any super class of T (parent class of T of any level). But I really struggle to imagine any real life example for this generic bound wildcard.

I understand what <? super T> means and I have seen this method:

public class Collections {
  public static <T> void copy(List<? super T> dest, List<? extends T> src) {
      for (int i = 0; i < src.size(); i++)
        dest.set(i, src.get(i));
  }
}

I am looking for an example of real life use case where this construction can be used and not for an explanation of what it is.


Solution

  • The easiest example I can think of is:

    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }
    

    taken from the same Collections. This way a Dog can implement Comparable<Animal> and if Animal already implements that, Dog does not have to do anything.

    EDIT for a real example:

    After some email ping-pongs, I am allowed to present a real example from my work-place (yay!).

    We have an interface called Sink (it does not matter what it does), the idea is that is accumulates things. The declaration is pretty trivial (simplified):

    interface Sink<T> {
        void accumulate(T t);
    }
    

    Obviously there is a helper method that takes a List and drains it's elements to a Sink (it's a bit more complicated, but to make it simple):

    public static <T> void drainToSink(List<T> collection, Sink<T> sink) {
        collection.forEach(sink::accumulate);
    }
    

    This is simple right? Well...

    I can have a List<String>, but I want to drain it to a Sink<Object> - this is a fairly common thing to do for us; but this will fail:

    Sink<Object> sink = null;
    List<String> strings = List.of("abc");
    drainToSink(strings, sink);
    

    For this to work we need to change the declaration to:

    public static <T> void drainToSink(List<T> collection, Sink<? super T> sink) {
        ....
    }