就在我认为自己是Java泛型的超级专家时,一个简单的事情就让我想到了一个循环。我在Eclipse 4.6.3中使用Java 8。
假设我为FooBar
制作了一个有关排序的枚举,我希望每个枚举值都能给我一个适合排序的Comparator<? extends FooBar>
:
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());
//…
}
}
}
是的,这就像一个魅力,就像我想的那样! (是的,这里我可以使用方法引用,但现在忽略它 - 这与此处的问题无关。)现在添加BY_FOO_DESCENDING
的比较器。
嗯...首先,Eclipse的自动完成似乎不适用于返回的比较器。没关系---我知道如何阅读Javadocs,所以我补充一下:
case BY_FOO_DESCENDING:
return Comparator.comparing(fooBar -> fooBar.getFoo()).reversed();
Eclipse现在告诉我:Cannot infer type argument(s) for <T, U> comparing(Function<? super T,? extends U>)
还有:The method getFoo() is undefined for the type Object
现在为什么getFoo()
在第一个示例中工作得很好,但是当我从返回的Comparator值调用方法时,它不起作用?如果Eclipse / Java知道早期代码中有FooBar
getFoo()
方法,为什么在返回值上添加reversed()
方法会改变什么?
这是多么愚蠢:查看Comparator.reversed())
的源代码;它只返回Collections.reverseOrder(this)
。因此,如果我将代码更改为以下代码,它可以正常工作:
case BY_FOO_DESCENDING:
return Collections.reverseOrder(Comparator.comparing(fooBar -> fooBar.getFoo()));
这是一个Eclipse错误吗?或者Java在泛型方面仍然有点愚蠢?或者我错过了什么?
我真的想使用Comparator.reversed()
,所以如果你告诉我一些演员或<blah>
我可以添加到表达式以使其工作,那将是很好的。感谢。