18

我意识到 Java 8 lambda 实现可能会发生变化,但在 lambda build b39 中,我发现只有当 lambda 表达式返回非 void 类型时才能省略大括号。例如,这编译:

public class Collections8 {
        public static void main(String[] args) {
                Iterable<String> names = Arrays.asList("Alice", "Bob", "Charlie");
                names.filter(e -> e.length() > 4).forEach(e -> { System.out.println(e); });
        }
}

但是像这样删除大括号:

names.filter(e -> e.length() > 4).forEach(e -> System.out.println(e));

给出错误

Collections8.java:6: error: method forEach in interface Iterable<T> cannot be applied to given types;
        names.filter(e -> e.length() > 4).forEach(e -> System.out.println(e));
                                         ^
  required: Block<? super String>
  found: lambda
  reason: incompatible return type void in lambda expression
  where T is a type-variable:
    T extends Object declared in interface Iterable

谁能解释这里发生了什么?

4

4 回答 4

23

当 lambda 主体是单个表达式或 void 方法调用时,您可以省略大括号。每个表达式的计算结果都是一个值,因此不能为空。

如果 lambda 的主体是语句块(例如,一系列计算后跟一个return语句),或者 lambda 没有值(即有void返回类型)并且不是单个 void 方法调用,则必须使用该块形式,需要括号。

在块式 lambda 中,如果一个值是returned,那么所有可能的代码路径必须是return一个值或throw一个Throwable.

于 2012-06-21T20:10:44.397 回答
11

这只是在:EG(大部分)已经对语法做出了决定。

在考虑了许多替代方案后,我们决定基本上采用 C# 语法。我们可能仍会进一步考虑细节(例如,细箭头与粗箭头,特殊的 nilary 形式等),并且尚未就方法引用语法做出决定。

C# 语法是:

lambda = ArgList Arrow Body
ArgList = Identifier
           | "(" Identifier [ "," Identifier ]* ")"
           | "(" Type Identifier [ "," Type Identifier ]* ")"
Body = Expression
           | "{" [ Statement ";" ]+ "}"

表达式的计算结果是某种东西,Java 中不能有 void 表达式。这是一个声明,因此您需要{}围绕它。

http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html

于 2012-06-21T20:15:03.610 回答
2

如果没有大括号,则 lambda 会自动返回 -> 运算符之后的一个表达式。
因此,当您有一个不返回任何内容的 lambda 时,您必须使用大括号

于 2013-04-08T15:58:18.243 回答
2

我已经尝试过您的代码,并且对于最新的 JRE 版本,我认为可以。

以下是我从 Oracle Java 文档中引用的内容。

在 lambda 表达式中,您必须将语句括在大括号 ( {}) 中。但是,您不必将 void 方法调用括在大括号中。
例如,以下是一个有效的 lambda 表达式:

email -> System.out.println(email)

医生解释得很清楚。希望这可以解决您的问题。

参考资料:https ://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

于 2015-11-05T14:37:47.510 回答