为什么具有 void return 类型方法的功能接口接受任何 return 类型方法?

Why does functional interface with void return-type method accept any return-type method?

我们有这个代码:

public class Test {
    public static Object foo() {
        System.out.println("Foo");
        return new Object();
    }

    public static void main(String[] args) {
        J j = Test::foo;
        j.m();
    }

}
interface J {
    void m();
}

此代码将有效。关键的一行是

J j = Test::foo;

尽管 interface J 声明它有一个 void 函数,Test::foo returns 一个 Object.

虽然我们不能在实现接口时重写方法(这是显而易见的)。 仅当接口的方法为void时才有效,否则代码将无法编译。有人能说出为什么它会以这种方式工作吗? :D

我不确定到底是什么让您感到困惑,所以您可以通过其他方式查看您的示例。


J j = Test::foo;

可以改写为

J j = () -> Test.foo();

因为它从 J 功能接口向 m() 方法提供主体,并且该方法不需要任何参数(这就是它以 () -> 开头的原因)。

但这可以看作是

的较短版本
J j = new J(){
    public void m(){
        Test.foo(); //correct despite `foo` returning value    
    }
};

这是正确的,因为 Java 允许我们忽略被调用方法的返回值,就像 List#add(E element) 的 returns boolean 值一样,但我们仍然是允许编写类似 list.add(1) 的代码而无需处理返回值。

Although interface J declares it has a void function, Test::foo returns an Object.

Test::foo returns 是不准确的。在不同的上下文中,它可能意味着不同的东西。

Supplier<Object>  a = Test::foo;
J                 b = Test::foo;
Runnable          c = Test::foo;

更准确的说法是 Test::foo 可以表示 a target type the functional method 其中 returns 可以是 void 也可以是 Object

这是expression statement (jls-14.8)的一个例子。

If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2).
...
An expression statement is executed by evaluating the expression; if the expression has a value, the value is discarded.