一个 java lambda 方法重载和表达式简写相关的问题?

新手上路,请多包涵

题目描述

一个方法,参数类型有 InterfaceA 和 InterfaceB 两种。抽象方法的参数都是int,返回值一个是void,另一个是int。
main方法中调用3次,只有第2个出错。为什么?
在我看来,这三个似乎并没有区别,要么都错,要么都正确。对比调用1和调用2,分号和花括号不是都可以省略的吗?对比调用2和调用3,int似乎没有什么必要?因为两个抽象方法要求的参数类型都是int。
我没有在书上翻到为什么省略花括号会有这样的影响,google了一下,都是说模糊的声明会导致两个都匹配,但没有提到为什么表达式的格式会造成这样的区别。

相关代码

public class LambdaDemo {
    public static void main(String[] args) {
        // 调用1
        method(m -> {System.out.println(m);}, 5);
        // 调用2
        method(m -> System.out.println(m), 5);
        // 调用3
        method((int m) -> System.out.println(m), 5);
    }

    static void method(InterfaceA a, int x) {
        a.test(x);
    }
    
    static void method(InterfaceB b, int x) {
        b.foo(x);
    }

}

interface InterfaceA {
    void test(int x);
}

interface InterfaceB {
    int foo(int x);
}
阅读 1.8k
1 个回答

第一个 method(m -> {System.out.println(m);}, 5); 其实很清楚,因为你用 {} 包起来了,没有 return 返回值,编译器推断为 InterfaceA 很正常。

第二个第三个其实都可以推断为 InterfaceA,因为很明显 System.out.println 返回的必然是 void,但是为什么第二个没有推断出来,我个人觉得这个是编译器方便的逻辑问题。
可能是由于你加了 (int) 强转 触发了编译器推断了 System.out.println 的返回值为 void

编译器也是人写的代码,遇见一些逻辑悖论处理让人无法理解,归根到底可能只是一个小小的逻辑问题。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题