2

Just when I think I am a super-expert in Java generics, a simple thing throws me for a loop. I'm using Java 8 in Eclipse 4.6.3.

Let's say I make an enum of orderings for FooBar, and I want each enum value to give me a Comparator<? extends FooBar> appropriate for the ordering:

public enum FooBarOrdering {
  BY_FOO_ASCENDING, BY_FOO_DESCENDING;

  public Comparator<? extends FooBar> getComparator() {
    switch (this) {
      case BY_FOO_ASCENDING:
        return Comparator.comparing(fooBar -> fooBar.getFoo());
      //…
    }
  }
}

Yay, that works for a charm, just like I thought it would! (Yes, here I could use a method reference, but ignore that for now ---that's irrelevant to the issue here.) Now to add the comparator for BY_FOO_DESCENDING.

Hmmm... first of all, Eclipse's auto-complete doesn't seem to work on the returned comparator. Never mind --- I know how to read Javadocs, so I add this:

case BY_FOO_DESCENDING:
  return Comparator.comparing(fooBar -> fooBar.getFoo()).reversed();

Eclipse now tells me: Cannot infer type argument(s) for <T, U> comparing(Function<? super T,? extends U>)

And also: The method getFoo() is undefined for the type Object

Now why did getFoo() work just fine in the first example, but did not work when I call a method from the returned Comparator value? If Eclipse/Java knew that there was a FooBar with a getFoo() method in the earlier code, why did adding a reversed() method on the return value change anything?

And here's how silly it gets: look at the source code for Comparator.reversed()); it simply returns Collections.reverseOrder(this). So if I change the code to the following, it works fine:

case BY_FOO_DESCENDING:
  return Collections.reverseOrder(Comparator.comparing(fooBar -> fooBar.getFoo()));

So is this an Eclipse bug? Or is Java still just a bit dumb when it comes to generics? Or am I missing something?

I would really like to use Comparator.reversed(), so if you tell me some cast or <blah> I can add to the expression to make it work, that would be nice. Thanks.

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272

0 Answers0