编程语言
首页 > 编程语言> > java – Thread.sleep的方法引用不明确

java – Thread.sleep的方法引用不明确

作者:互联网

我遇到了一个奇怪的问题,其中对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;
    }
}

我得到了这两个错误:

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)在这里发挥作用.为什么会这样?

编辑:使用javac版本1.8.0_111

解决方法:

您可以通过向类Test添加一个带有两个参数的方法sleep来重新创建自己类中的问题,如下所示:

public static void sleep(long millis) {
}

public static void sleep(long millis, int nanos) {
}

所以问题实际上是由于方法睡眠过载这一事实引起的.

JLS指示初始方法选择代码仅查看功能接口的类型参数的数量 – 仅在第二阶段中查看功能接口内的方法的签名.

JLS 15.13:

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>,而overload void sleep(long,int)可能与功能接口Foo< P,R>匹配.这就是为什么你得到“引用foo是模糊的”错误.

当它试图进一步看到如何匹配Foo< P,R>用函数方法R调用(P param1)到方法void sleep(long,int),它发现这实际上不可能,并且你得到另一个编译错误:

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)

标签:functional-interface,java,java-8
来源: https://codeday.me/bug/20191005/1855461.html