【发布时间】:2018-04-26 21:10:47
【问题描述】:
我遇到了一个奇怪的问题,即对 Thread::sleep 的方法引用不明确,但具有相同签名的方法却不明确。
package test;
public class Test
{
public static void main(String[] args)
{
foo(Test::sleep, 1000L); //fine
foo((FooVoid<Long>)Thread::sleep, 1000L); //fine
foo(Thread::sleep, 1000L); //error
}
public static void sleep(long millis) throws InterruptedException
{
Thread.sleep(millis);
}
public static <P, R> void foo(Foo<P, R> function, P param) {}
public static <P> void foo(FooVoid<P> function, P param) {}
@FunctionalInterface
public interface Foo<P, R> {
R call(P param1) throws Exception;
}
@FunctionalInterface
public interface FooVoid<P> {
void call(P param1) throws Exception;
}
}
我得到了这 2 个错误:
Error:(9, 17) java: reference to foo is ambiguous
both method <P,R>foo(test.Test.Foo<P,R>,P) in test.Test and method <P>foo(test.Test.FooVoid<P>,P) in test.Test match
Error:(9, 20) java: incompatible types: cannot infer type-variable(s) P,R
(argument mismatch; bad return type in method reference
void cannot be converted to R)
我看到的唯一区别是Thread::sleep 是native。它有什么改变吗?我不认为过载Thread::sleep(long, int) 在这里发挥作用。为什么会这样?
编辑:使用 javac 版本 1.8.0_111
【问题讨论】:
-
有趣的是,Mars.2 Release (4.5.2) 中的Eclipse java编译器对你的代码没有任何问题。
-
@ErwinBolwidt 当我在 IntelliJ 中切换到 Eclipse 编译器时,我收到一条不同的错误消息,含义相同。不知道编译器的版本是什么。
-
我尝试通过评论它编译的这个方法。 // public static
void foo(Foo
function, P param) { // }
-
@ErwinBolwidt Eclipse Mars (4.5) had a bug 在这个区域。由于 Neon (4.6) 也 ECJ 报告了歧义。 Winter 在切换到 ECJ 时必须使用 >= 4.6 的版本。
标签: java java-8 functional-interface