在下面的代码片段中,forEach()
的两种用法都可以编译:
public static void main(String[] args)
{
BigDecimal spent = BigDecimal.ZERO;
Stream.of(BigDecimal.ONE, BigDecimal.TEN).forEach(spent::add);
Set<BigDecimal> set = new HashSet<>();
Stream.of(BigDecimal.ONE, BigDecimal.TEN).forEach(set::add);
}
我知道第一个示例的空洞(BigDecimal
是不可变的);问题不在这里:
Stream
的forEach()
接受Consumer
作为参数,SAM 的签名(注意:单一抽象方法)表示它返回void
;- 然而,
BigDecimal
的.add()
返回一个BigDecimal
,而Set
的.add()
(实际上是Collection
)返回一个boolean
; - 因此上述两种方法的签名都不匹配
Consumer
; - 但两个示例都可以编译。
但是这个不编译:
// whatever is returned; BigDecimal.ZERO, null... -> compile error
Stream.of(BigDecimal.ONE).forEach(b -> { return false; });
是设计使然吗?
最佳答案
Remember that a return type is not part of a method signature.对于您的第一个案例,我们转到 runtime evaluation of the lambda expression .
The method's body has the effect of evaluating the lambda body, if it is an expression, or of executing the lambda body, if it is a block; if a result is expected, it is returned from the method.
关于第二种情况
If the function type's result is
void
, the lambda body is either a statement expression or a void-compatible block.
你的不是,即。 Consumer#accept(Object)
的函数类型是void
,但是你的 lambda 体既不是语句表达式也不是 a void-compatible block .它是一个值兼容的 block 。
Is it by design?
我说是的。在第二种情况下,您明确声明要返回一个值。但目标功能接口(interface)方法不允许这样做。
在你的第一个片段中
Stream.of(BigDecimal.ONE, BigDecimal.TEN).forEach(spent::add);
您只是拥有更大的灵 active 。该表达式可能有副作用,您可能希望忽略返回值。
关于java - 方法引用不符合功能接口(interface),但编译不会失败......是设计使然吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27209023/