Thread.sleep的方法引用不明确 [英] Method reference is ambiguous for Thread.sleep
问题描述
我遇到一个奇怪的问题,其中对 Thread :: sleep
的方法引用是不明确的,但具有相同签名的方法不是。
I've come across a weird problem where a method reference to Thread::sleep
is ambiguous but a method with the same signature is not.
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;
}
}
我收到了这两个错误:
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
是天然
。它有什么改变吗?我不认为重载 Thread :: sleep(long,int)
在这里发挥作用。为什么会这样?
The only difference I see is that Thread::sleep
is native
. Does it change anything? I don't think the overload Thread::sleep(long, int)
comes into play here. Why does it happen?
编辑:使用javac版本1.8.0_111
Using javac version 1.8.0_111
推荐答案
您可以通过添加方法 sleep
来重新创建您自己类中的问题,其中包含两个类Test的参数,如下所示:
You can recreate the problem in your own class by adding a method sleep
with two arguments to class Test like below:
public static void sleep(long millis) {
}
public static void sleep(long millis, int nanos) {
}
所以这个问题实际上是由于方法sleep被重载引起的。
So the problem is really caused by the fact that the method sleep is overloaded.
JLS表示初始方法选择代码只查看功能接口的类型参数的数量 - 仅在第二阶段它会查看内部方法的签名功能界面。
The JLS indicates that the initial method selection code only looks at the number of type arguments to the functional interface - only in the second phase does it look at the signature of the method inside the functional interface.
无法指定要匹配的特定签名ed,
例如,Arrays :: sort(int [])。相反,函数接口
提供了用作重载
分辨率算法(第15.12.2节)的输入的参数类型。
It is not possible to specify a particular signature to be matched, for example, Arrays::sort(int[]). Instead, the functional interface provides argument types that are used as input to the overload resolution algorithm (§15.12.2).
(本节倒数第二段)
所以在的情况下,Thread :: sleep
, void sleep(long)
可能与功能界面 FooVoid< P>
匹配,而重载 void sleep(long,int)
可能匹配功能接口 Foo< P,R>
。这就是为什么你得到引用foo是模糊的错误。
So in the case of Thread::sleep
, void sleep(long)
potentially matches functional interface FooVoid<P>
, while overload void sleep(long, int)
potentially matches functional interface Foo<P, R>
. That's why you get the "reference to foo is ambiguous" error.
当它试图进一步看看如何匹配 Foo< P时, R>
使用函数方法 R调用(P param1)
到方法 void sleep(long,int)
,它发现这实际上是不可能的,并且你得到另一个编译错误:
When it tries to go further and see how to match Foo<P, R>
with functional method R call(P param1)
to the method void sleep(long, int)
, it finds out that this is not actually possible, and you get another compile error:
test/Test.java:7: error: incompatible types: cannot infer type-variable(s) P,R
foo(Thread::sleep, 1000L); // error
^
(argument mismatch; bad return type in method reference
void cannot be converted to R)
这篇关于Thread.sleep的方法引用不明确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!