Почему я не могу использовать метку продолжения с Collections # forEach в Java 8? - PullRequest
0 голосов
/ 13 февраля 2019

Следующие компиляции без ошибок:

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?

1 Ответ

0 голосов
/ 13 февраля 2019

Как указано в комментариях, forEach - это просто вызов метода.Фрагмент

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

представляет собой помеченный оператор :

метки операторов идентификатора используются с break или continue операторами (§14.15, §14.16) появляется в любом месте внутри помеченного оператора.

Повторим, помеченный оператор является выражением вызова метода.Ваше заявление continue не входит в помеченное заявление.

Ваш оператор continue находится внутри оператора while, появляющегося в теле лямбда-выражения.

Оператор continue с меткой Identifier пытается передать управление во вложенную маркированную инструкцию (§14.7), которая имеет тот же Identifier, что и его метка;этот оператор, который называется целью продолжения, немедленно завершает текущую итерацию и начинает новую.

[...]

Цель продолжения должна быть while, *Оператор 1033 *, for или ошибка времени компиляции. Оператор

continue должен ссылаться на метку внутри непосредственно включающего метода, конструктора, инициализатора или лямбда-тела.Нет нелокальных прыжков. Если ни один помеченный оператор с Identifier в качестве метки в непосредственно включающем теле метода, конструктора, инициализатора или лямбды не содержит оператора continue, возникает ошибка времени компиляции .

Поскольку в непосредственно включающем теле лямбды-тела нет помеченного (while, do или for) оператора с именем myLabel, вы получаете ошибку времени компиляции.

...