Generics oddness

Ben Evans benjamin.john.evans at gmail.com
Tue May 29 08:07:09 PDT 2012


Hi,

At Sunday's Lambdas Hackday, we discovered an issue with Apache
Cassandra's use of Google Guava.

Specifically, Guava defines an Ordering<T> class which implements Comparator<T>.

Ordering<T> defines reverse(), which is of course now present on
Comparator<T>, and causes javac to complain:

This reduces to the following test case:

public class Ordering<T> implements Comparator<T> {
    @Override
    public int compare(T o1, T o2) {
        // ...
    }

    public <S extends T> Ordering<S> reverse() {
        // ...
    }
}

public class OrderingMain<T> {
        Ordering<T> myOrdering;

        public Ordering<T> get() {
            return myOrdering.reverse();
        }
}

This compiles fine under JDK 7.

Under JDK 8 Ordering<T> compiles fine. OrderingMain<T> fails with this error:

hackday1/OrderingMain.java:20: error: reference to reverse is
ambiguous, both method reverse() in Comparator and method <S>reverse()
in Ordering match
            return myOrdering.reverse();
                             ^
  where T#1,S,T#2 are type-variables:
    T#1 extends Object declared in interface Comparator
    S extends T#2 declared in method <S>reverse()
    T#2 extends Object declared in class Ordering
hackday1/OrderingMain.java:20: error: incompatible types
            return myOrdering.reverse();
                                     ^
  required: Ordering<T>
  found: Comparator<T>
  where T is a type-variable:
    T extends Object declared in class OrderingMain
2 errors

I've stared at this extensively over the last couple of days, and come
to the conclusion that I don't understand this behaviour.

Is this a bug? If not, can someone untangle what's happening here for me?

Thanks,

Ben


More information about the lambda-dev mailing list