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



我们有这个代码:

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返回一个Object

虽然我们不能在实现接口时覆盖方法(这很明显(。 这仅在接口的方法void时有效,否则代码将无法编译。有人能说出为什么它的工作方式是这样工作的吗?:D

尽管interface J声明它具有void函数,但Test::foo返回一个Object

Test::foo返回某些东西是不准确的。在不同的上下文中,它可能意味着不同的事情。

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

更准确地说,Test::foo可以表示一个目标类型,其函数方法返回voidObject

这是表达式语句 (jls-14.8( 的一个示例。

如果目标类型的函数类型具有void返回,则 lambda 主体是语句表达式(§14.8( 或与 void 兼容的块 (§15.27.2(。
...
表达式语句通过计算表达式来执行;如果表达式具有值,则丢弃该值。

我不确定到底是什么让你感到困惑,所以这里有一些其他方法可以查看你的示例。


J j = Test::foo;

可以改写为

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

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

但这可以看作是较短的版本

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

这是正确的,因为 Java 允许我们忽略被调用方法的返回值,例如在返回boolean值的情况下List#add(E element),但我们仍然可以像list.add(1)一样编写代码,而不必处理返回值。

相关内容

  • 没有找到相关文章

最新更新