java.util.Comparator.naturalOrder takes a <T extends Comparable<? super T>> and returns a Comparator<T> - why?

bounded-wildcard, comparator, generics, java, java-8

Solution

This compiles:

import java.util.*;

class Foo<T extends Comparable<? super T>> {

    private Comparator<T> comparator;

    public void someMethod(Comparator<T> comparator)
    {
       this.comparator = comparator;                  // no compile error
       this.comparator = Comparator.<T>naturalOrder(); // <T> is optional, compiler can infer
    }
}

The simplest way to think about it is this: you are trying to use type T with the Comparator interface, which imposes certain requirements on it (in particular it has that fancy recursive requirement that T must implement Comparable interface). You do not impose such requirement when genericising (?) your class, so compiler is not happy. Your requirements on T must be as strong as the class that you are using it with.

You are confused about what natural ordering method does. It just takes a class which implements Comparable and creates the default Comparator for it. No way around it -- you can't create a Comparator for something that is not Comparable.

You want TreeMap to require Comparable, but you can't, because it is a valid case to use something that is not comparable, as long as you have provided a Comparator. So TreeMap ends up not enforcing Comparable and just casts explicitly at runtime (and throws an exception).

Problem

(If this is a duplicate please point me to the right answer! I searched and read several (>5) related questions but none seemed on the mark. Also looked at the Generics FAQ and other sources...) It is apparently proper practice that when a collection class takes a comparator it should have the type `Comparator<? super T>` for your parameterized type `T`. And you can see that lots of places, e.g., `TreeMap`. Okay. My problem is working with `Comparator.naturalOrder()` which is parameterized on `T extends Comparable<? super T>` but returns a `Comparator<T>`. I'm trying to have a field in my collection class that holds either the user-specified comparator or the `Comparator.naturalOrder` comparator. I can't get it to work. My questions, all related, are: - How is `Comparator.naturalOrder` properly used? - And can I do what I want which is have a field where I store either a user-supplied comparator or the `naturalOrder` comparator? - Given that most collection classes (in the framework) are parameterized on `T` not `T implements Comparable<? super T>`, so that's the design pattern chosen, how is `naturalOrder` useful since it requires the latter bounded wildcard, not the unconstrained type parameter? Thanks! Here follows the actual examples with compiler errors: So: If I have code like this in some class where T has no bounds (as in all existing collection classes): ``` class Foo<T> { private Comparator<? super T> comparator; public void someMethod(Comparator<? super T> comparator) { this.comparator = comparator; // no compile error this.comparator = Comparator.naturalOrder(); // incompatible types } } ``` with this error: ``` Error:(331, 50) java: incompatible types: inferred type does not conform to upper bound(s) inferred: T upper bound(s): java.lang.Comparable<? super T> ``` So if I decide to forgo the advantages of `? super T` then I have: ``` class Foo<T> { private Comparator<T> comparator; public void someMethod(ComparatorT> comparator) { this.comparator = comparator; // no compile error this.comparator = Comparator.naturalOrder(); // incompatible types } } ``` where I have ``` Error:(nnn, 50) java: incompatible types: inference variable T has incompatible bounds equality constraints: T upper bounds: java.lang.Comparable<? super T> ```

Original source