以下代码使用 javac 和 Eclipse 4.6.1/4.6 进行编译,但在 Eclipse 4.6.2 中产生错误:
package ecbug;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Foo
{
class A
{
public int getStart() { return 0; }
}
void someMethod(List<A> toRemove)
{
Collections.sort(toRemove, Comparator.comparing(t -> -t.getStart()));
}
}
Eclipse 4.6.2 提示,在-t.getStart()
下,存在类型不匹配:无法从 int 转换为 Comparable<? super 可比 super U>>.
我认为 Comparator.comparing(...)
的论点应该是Comparable<T>
与 T = A
,使用函数方法 compareTo返回 int
。 Eclipse 似乎认为 lambda 函数应该返回 Comparable super 可比>。
我强烈怀疑 Eclipse 存在 bug,但是在某些情况下 Eclipse 已经正确实现了语言规范,而 javac 没有,所以似乎值得问:这是 Eclipse bug 还是 < em>javac 错误?任何语言律师都可以指出语言规范的相关部分吗?
可能相关的问题,在我看来这些问题并不重复:
Java 8 Stream flatMap and group by code compiler error - 类似的错误消息,但不清楚是否是完全相同的问题; Answer 声称这是一个 Eclipse bug,但没有提供 bug 链接或 JLS 引用;指旧的 Eclipse 版本。
Why didn't this java 8 example using type inference compile in Eclipse? - 与之前类似
Java Stream collect after flatMap returns List<Object> instead of List<String> - 同样,可能是一个不同的问题;评论声称 Eclipse 存在问题,但没有通过引用 JLS 来证明其合理性,也没有提供 Eclipse 错误报告的链接。
最佳答案
你的解释不符合要求。 Comparator.comparing(...)
的参数(单参数版本)不应该是 Comparable<T>
,而是 Function<? super T,? extends U>
,而T := A
,但是U
是U extends Comparable<? super U>
.
所以当你说
Eclipse seems to believe that the lambda function should return
Comparable<? super Comparable<? super U>>
您对 Eclipse 的期望是正确的,Eclipse 的期望也是正确的。
但是你的函数返回 int
应该比较的值,当您将该值框到 Integer
时,您有一个满足预期 U extends Comparable<? super U>
的类型约束,如Integer
实现Comparable<Integer>
。换句话说,U
应该推断为Integer
,但显然,这个特定的 Eclipse 版本由于需要装箱 int
而无法执行此操作。至Integer
.
作为旁注,当您想要比较int
时属性,您可能需要使用 Comparator.comparingInt(...)
反正。通过这个工厂,返回的比较器避免了 int
的装箱。至Integer
总共。
此外,您不应通过求反来反转整数顺序。问题是
-Integer.MIN_VALUE == Integer.MIN_VALUE
,试图否定尽可能小的 int
值导致溢出评估为最小 int
再次值,而不是最大的值。使用否定来颠倒顺序可能在很多情况下都有效,在其中一些情况下,这可能是合理的,因为可以排除这种特殊值,但是,它会产生一个坏习惯,在这种情况可能发生的情况下可能会适得其反。 ,当然,很少,通常只在客户那里......
正确的习惯用法是
Collections.sort(toRemove, Comparator.comparingInt(A::getStart).reversed());
其工作原理是交换两个元素进行比较,这在所有场景下都有效,并且没有性能缺陷。
关于java - Eclipse 或 Javac 错误; lambda 类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42113629/