ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-10-05 06:10:34  阅读:170  来源: 互联网

标签:functional-interface java java-8


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有