【发布时间】:2015-03-28 22:47:55
【问题描述】:
我在以下代码中遇到错误,我认为它不应该存在...使用 JDK 8u40 编译此代码。
public class Ambiguous {
public static void main(String[] args) {
consumerIntFunctionTest(data -> {
Arrays.sort(data);
}, int[]::new);
consumerIntFunctionTest(Arrays::sort, int[]::new);
}
private static <T> void consumerIntFunctionTest(final Consumer<T> consumer, final IntFunction<T> generator) {
}
private static <T> void consumerIntFunctionTest(final Function<T, ?> consumer, final IntFunction<T> generator) {
}
}
错误如下:
Error:(17, 9) java: 对 consumerIntFunctionTest 的引用不明确 net.tuis.ubench.Ambiguous 中的方法 consumerIntFunctionTest(java.util.function.Consumer,java.util.function.IntFunction) 和 net 中的方法 consumerIntFunctionTest(java.util.function.Function,java.util.function.IntFunction) .tuis.ubench.Ambiguous 匹配
错误发生在以下行:
consumerIntFunctionTest(Arrays::sort, int[]::new);
我相信应该没有错误,因为所有Arrays::sort 引用都是void 类型的,并且它们都没有返回值。如您所见,当我显式扩展 Consumer<T> lambda 时,它确实工作。
这真的是 javac 中的一个错误,还是 JLS 声明 lambda 在这种情况下无法自动展开?如果是后者,我仍然认为这很奇怪,因为 consumerIntFunctionTest 与第一个参数 Function<T, ?> 不应该匹配。
【问题讨论】:
-
JLS 中应该定义的位置是15.27.3。 (没仔细看)。
-
为什么你认为
Function<T, ?>不匹配??也可以是Void,所以它匹配。 -
我会说它必须是某种错误:当注释掉
Consumer方法时,它抱怨它可以not调用带有给定 lambda 的Function- 方法 - 因此,无论如何它都不能模棱两可。有趣:当将参数声明为(int[] data)(因此,使其成为显式类型 lambda)时,它会正确地将其解析为Consumer版本。在正文中另外插入return null;时,它会解析为Function版本。所以它显然在 implicitly typed 和 void compatible lambda(如 JLS 中定义)上绊倒了。 -
我得到了同样的错误,但由于 tomse 声明代码在 1.8.0_25 下编译,这可能是 1.8.0_40 特有的问题。或许尝试在1.8.0_25下运行看看代码是否编译?
-
@EddyG 鉴于您认为存在 javac 错误的时间与 实际上 的时间相比,我认为首先在 Stackoverflow 上写一个问题更合适,然后才写一个错误报告。作为记录,我确实在几个小时前提交了它,但我仍在等待它是否会被接受。