20

I want to have an interface A parameterised by T A<T>, and also want every class that implements it to also implement Comparable (with T and its subtypes). It would seem natural to write interface A<T> extends Comparable<? extends T>, but that doesn't work. How should I do it then?

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
oceola
  • 241
  • 1
  • 2
  • 4
  • 1
    I would also refer you to Java Generics FAQ (http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ204), which will give you more ideas regarding `Comparable`. – dma_k Feb 09 '10 at 19:47

2 Answers2

21

When Comparable<? extends T> appears it means you have an instance of Comparable that can be compared to one (unknown) subtype of T, not that it can be compared to any subtype of T.

But you don't need that, because a Comparable<T> can compare itself to any subtype of T anyway, e.g. a Comparable<Number> can compare itself to a Comparable<Double>.

So try:

interface A<T> extends Comparable<T> {
    // ...
}

or

interface A<T extends Comparable<T>> extends Comparable<A<T>> {
    // ...
}

depending on whether you need to be able to compare instances of T in order to implement your compareTo method.

finnw
  • 47,861
  • 24
  • 143
  • 221
  • This is an awesome answer! I came here from http://stackoverflow.com/questions/6290406/generic-method-to-sort-a-map-on-values. Solved my problem. – Swaranga Sarma Jun 09 '11 at 09:41
2

If you use comparable you do not need to specify the possibility for subtypes in the compare function, it is by nature possible to pass in any subtype of an object X into a method that declared a parameter of class X. See the code below for more information.

public interface Test<T> extends Comparable<T> {

}

class TestImpl implements Test<Number> {
    @Override
    public int compareTo(final Number other) {
        return other.intValue() - 128;
    }
}

class TestMain {
    public static void main(final String[] args) {
        TestImpl testImpl = new TestImpl();
        testImpl.compareTo(Integer.MIN_VALUE);
    }
}
Nils Schmidt
  • 3,702
  • 6
  • 23
  • 28