在下面的代码片段中,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; });是故意的吗?
发布于 2014-11-30 01:37:43
请记住,返回类型不是方法签名的一部分。,对于你的第一个案例,我们去lambda表达式的运行时计算。
该方法的主体具有这样的效果:如果是表达式,则计算lambda主体;如果它是块,则执行lambda主体;如果预期结果,则从方法返回它。
至于第二个案件
如果函数类型的结果是
void,那么lambda主体要么是一个语句表达式,要么是一个与空兼容的块。
而你的不是.Consumer#accept(Object)的函数类型是void,但是您的lambda主体既不是语句表达式,也不是一个与空相兼容的块,它是一个与值兼容的块。
是故意的吗?
我答应了。在第二种情况下,您将显式地声明您正在返回一个值。但目标函数接口方法不允许这样做。
在你的第一个片段
Stream.of(BigDecimal.ONE, BigDecimal.TEN).forEach(spent::add);你只是有更多的灵活性。表达式可能有副作用,您可能想忽略返回的值。
https://stackoverflow.com/questions/27209023
复制相似问题