title: Why do we need bounded wilcard <? extends T> in Collections.max() method
body: <p>I've read awesome "Effective Java" by Joshua Bloch. But one example in the books is left unclear to me. It's taken from chapter about generics, exact item is <strong>"Item 28: Use bounded wildcards to increase API flexibility"</strong>.</p>
  
  <p>In this item it's shown how to write the most universal and bulletproof (at the type system point of view) version of the algorithm of selection maximum element from collection using bounded type parameters and bounded wildcard types.</p>
  
  <p>The final signature of the static method written looks like this:</p>
  
  <pre><code>public static &lt;T extends Comparable&lt;? super T&gt;&gt; T max(List&lt;? extends T&gt; list)
  </code></pre>
  
  <p>And it's mostly the same as the one of <code>Collections#max</code> function from standard library.</p>
  
  <pre><code>public static &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt; T max(Collection&lt;? extends T&gt; coll) 
  </code></pre>
  
  <p>I understand why we need bounded wildcard in <code>T extends Comparable&lt;? super T&gt;</code> type constraint, but is it really necessary in type of the argument? It seems to me that it will be the same if we leave just <code>List&lt;T&gt;</code> or <code>Collection&lt;T&gt;</code>, isn't it? I mean something like this:</p>
  
  <pre><code>public static &lt;T extends Comparable&lt;? super T&gt;&gt; T wrongMin(Collection&lt;T&gt; xs)
  </code></pre>
  
  <p>I've written the following silly example of using both signatures and don't see any diferrence:</p>
  
  <pre><code>public class Algorithms {
      public static class ColoredPoint extends Point {
          public final Color color;
  
          public ColoredPoint(int x, int y, Color color) {
              super(x, y);
              this.color = color;
          }
          @Override
          public String toString() {
              return String.format("ColoredPoint(x=%d, y=%d, color=%s)", x, y, color);
          }
      }
  
      public static class Point implements Comparable&lt;Point&gt; {
          public final int x, y;
  
          public Point(int x, int y) {
              this.x = x;
              this.y = y;
          }
          @Override
          public String toString() {
              return String.format("Point(x=%d, y=%d)", x, y);
          }
          @Override
          public int compareTo(Point p) {
              return x != p.x ? x - p.x : y - p.y;
          }
      }
  
      public static &lt;T extends Comparable&lt;? super T&gt;&gt; T min(Collection&lt;? extends T&gt; xs) {
          Iterator&lt;? extends T&gt; iter = xs.iterator();
          if (!iter.hasNext()) {
              throw new IllegalArgumentException("Collection is empty");
          }
          T minElem = iter.next();
          while (iter.hasNext()) {
              T elem = iter.next();
              if (elem.compareTo(minElem) &lt; 0) {
                  minElem = elem;
              }
          }
          return minElem;
      }
  
      public static &lt;T extends Comparable&lt;? super T&gt;&gt; T wrongMin(Collection&lt;T&gt; xs) {
          return min(xs);
      }
  
      public static void main(String[] args) {
          List&lt;ColoredPoint&gt; points = Arrays.asList(
                  new ColoredPoint(1, 2, Color.BLACK),
                  new ColoredPoint(0, 2, Color.BLUE),
                  new ColoredPoint(0, -1, Color.RED)
          );
          Point p1 = wrongMin(points);
          Point p2 = min(points);
          System.out.println("Minimum element is " + p1);
      }
  </code></pre>
  
  <p>So can you suggest an example where such simplified signature will be inacceptable?</p>
  
  <p>P.S. And why the heck there is <code>T extends Object</code> in official implementation?</p>
  
  <h1>Answer</h1>
  
  <p>Well, thanks to @Bohemian I've managed to figure out what's the difference between them.</p>
  
  <p>Consider the following two auxiliary methods </p>
  
  <pre><code>private static void expectsPointOrColoredPoint(Point p) {
      System.out.println("Overloaded for Point");
  }
  
  private static void expectsPointOrColoredPoint(ColoredPoint p) {
      System.out.println("Overloaded for ColoredPoint");
  }
  </code></pre>
  
  <p>Sure, it's not very smart to overload method both for superclass and its subclass, but it let us see what type of return value was actually inferred (<code>points</code> is <code>List&lt;ColoredPoint&gt;</code> as before).</p>
  
  <pre><code>expectsPointOrColoredPoint(min(points));     // print "Overloaded for ColoredPoint"
  expectsPointOrColoredPoint(wrongMin(points)); // print "Overloaded for ColoredPoint"
  </code></pre>
  
  <p>For both methods inferred type was <code>ColoredPoint</code>. </p>
  
  <p>Sometimes you want be explicit about type passed to overloaded function. You may do it a couple of ways:</p>
  
  <p>You can cast:</p>
  
  <pre><code>expectsPointOrColoredPoint((Point) min(points));     // print "Overloaded for Point"
  expectsPointOrColoredPoint((Point) wrongMin(points)); // print "Overloaded for Point"
  </code></pre>
  
  <p>Still no difference...</p>
  
  <p>Or you can tell compiler what type should be inferred using syntax <em><code>class.&lt;type&gt;method</code></em>:</p>
  
  <pre><code>expectsPointOrColoredPoint(Algorithms.&lt;Point&gt;min(points));     // print "Overloaded for Point"
  expectsPointOrColoredPoint(Algorithms.&lt;Point&gt;wrongMin(points)); // will not compile
  </code></pre>
  
  <p>Aha! Here is the answer. <code>List&lt;ColoredPoint&gt;</code> can't be passed to function expecting <code>Collection&lt;Point&gt;</code> because generics are not covariant (unlike arrays), but can be passed to function expecting <code>Collection&lt;? extends Point&gt;</code>. </p>
  
  <p>I'm not sure where or who may prefer to use explicit type parameter in such case, but at least it shows where the <code>wrongMin</code> may be inappropriate.</p>
  
  <p>And thanks to @erickson and @tom-hawtin-tackline for answers about purpose of <code>T extends Object</code> constraint.</p>