【问题标题】:Why am I not able to use continue with a label with Collections#forEach in Java 8?为什么我不能在 Java 8 中继续使用带有 Collections#forEach 的标签?
【发布时间】:2019-02-13 03:08:57
【问题描述】:

以下编译没有任何错误:

class App {
    boolean b;
    boolean c;

    void foo(List<Integer> ints) {
        myLabel:
        for (Integer i : ints) {
            while (!b) {
                if (c) {
                    continue myLabel;
                }
            }
        };
    }
}

但是如果我修改foo如下:

void foo(List<Integer> ints) {
    myLabel:
    ints.forEach(integer -> {
        while (!b) {
            if (c) {
                continue myLabel;
            }
        }
    });
}

我收到Error:(17, 21) undefined label: myLabel

有什么区别?据我所知,新的forEach只是增强for循环的捷径?

【问题讨论】:

  • 因为你在一个单独的 (lambda) 函数中。
  • " 新的 forEach 只是增强 for 循环的快捷方式?" - 不,不是真的,它是一个采用闭包的方法,可以对传递给它的元素
  • @SLaks 但您可以访问 lambda 之外的变量。为什么不是标签?我想知道 JLS 是否指定了这个
  • 我实际上尝试过final myLabel 想同样的事情,这显然本身就是一个语法错误。 @尤金
  • 语法上完全不同,它只是一个方法调用。标签适用于循环而不是方法调用。

标签: java for-loop java-8 label


【解决方案1】:

如 cmets 中所述,forEach 只是一个方法调用。 sn-p

myLabel: ints.forEach(integer -> ...);

labeled statement:

标识符语句标签与出现在标记语句中的任何位置的breakcontinue 语句(§14.15、§14.16)一起使用。

重复一遍,带标签的语句是方法调用表达式。您的 continue 语句不在标记的语句中。

您的 continue statement 在出现在 lambda 表达式主体中的 while 语句中。

带有标签Identifiercontinue 语句尝试转移 控制具有相同的封闭标记语句(§14.7) Identifier 作为它的标签;该语句,称为 continue 目标,然后立即结束当前迭代并开始新的迭代 一个。

[...]

continue 目标必须是whiledofor 语句,否则会发生编译时错误。

continue 语句必须引用紧接内的标签 封闭方法、构造函数、初始化程序或 lambda 主体。有 没有非局部跳跃。 如果没有带有Identifier 的标记语句 立即封闭的方法、构造函数、初始化程序中的标签, 或 lambda body 包含 continue 语句,编译时错误 发生

由于在直接封闭的 lambda 主体中没有名为 myLabel 的标记(whiledofor)语句,因此会出现编译时错误。

【讨论】:

    猜你喜欢
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 2020-07-05
    • 2020-02-24
    • 1970-01-01
    • 2011-03-18
    相关资源
    最近更新 更多