为什么具有 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.
我们有这个代码:
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 avoid
function,Test::foo
returns anObject
.
说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.