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

BanzaiTokyo :

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.

Eugene :

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) {
    ....
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=34878&siteId=1