Помеченный разрыв сразу после l oop не работает в Java - PullRequest
2 голосов
/ 25 января 2020
for(int x = 0; x < 5; x++)
        stop2: {
                System.out.println("Count");
                if (x == 2)
                    break stop2;
        }

        stop3: for(int x = 0; x < 5; x++) {
                System.out.println("Second");
                if (x == 2)
                    break stop3;
        } 

Когда я изучал помеченный разрыв в Java, я заметил, что размещение метки непосредственно перед и после оператора for будет иметь разные результаты. В приведенном выше коде for l oop с stop2 не останавливается после печати «Count» 3 раза, в то время как другой делает. Может кто-нибудь объяснить разницу между этими двумя? Я думал, что помеченный разрыв разбивает тело сразу после ярлыка ...

Ответы [ 4 ]

4 голосов
/ 25 января 2020

У вас неправильный синтаксис (для вашего желаемого поведения) в первом примере. Это

for(int x = 0; x < 5; x++)
stop2: {
    System.out.println("Count");
    if (x == 2)
        break stop2;
}

должно быть

stop2: for (int x = 0; x < 5; x++) {
    System.out.println("Count");
    if (x == 2) {
        break stop2;
    }
}

или просто

for (int x = 0; x < 5; x++) {
    System.out.println("Count");
    if (x == 2) {
        break;
    }
}

, поскольку немаркированный break применяется к первому (что является самым внутренним) l oop когда на break.

не нанесена метка
3 голосов
/ 25 января 2020

Я думал, что помеченный разрыв разбивает тело сразу после ярлыка.

Нет. Это нарушает оператор (или блок), к которому прикреплена метка.

Таким образом:

  for (int x = 0; x < 5; x++)
      stop2: {
            // stuff
            break stop2;
      }

разрывает оператор тела for l oop, а

 stop3: for (int x = 0; x < 5; x++)
      {
          //stuff
          break stop3;
      }

- оператор for.

Сравните вышеприведенное с

for (int x = 0; x < 5; x++)
      {
          //stuff
          break;
      }

Обычный (без метки) break может использоваться только в al oop или в операторе switch, и он разрывает непосредственно включающую l oop или переключатель.

Вот что JLS 14.15 говорит по этому поводу:

"Оператор break без метки пытается передать управление самой внутренней оболочке switch , while, do или for оператор непосредственно включающего метода или инициализатора; этот оператор, который называется break target , затем сразу же завершается нормально. "

"Оператор break с меткой Identifier пытается передать управление во вложенную помеченную инструкцию (§14.7), которая имеет тот же Identifier, что и его метка; эта инструкция, которая называется цель прерывания , затем сразу же завершается нормально. В этом случае целью прерывания не обязательно должно быть выражение switch, while, do или for. "

Таким образом, ключевой момент в определении того, что делает оператор break (обычный или помеченный), заключается в том, чем является цель break .


Это все немного неясно .. и еще одна веская причина использовать помеченные операторы только тогда, когда они абсолютно необходимы. Я не вижу оправдания их использования в ваших примерах (кроме как в качестве иллюстрации). Один из них должен быть написан как обычный break, а другой должен быть записан как continue.

Но (для сомневающихся) оба эти примеры являются допустимым, компилируемым кодом Java и оба имеют четкое значение в соответствии с JLS.

1 голос
/ 25 января 2020
      for(int x = 0; x < 5; x++)
        stop2: {
                System.out.println("Count");
                if (x == 2)
                    break stop2;
        }

В этом случае, когда вы прерываете метку stop2, элемент управления снова возвращается к значению l oop и начинается со следующей итерации (x = 3).

        stop3: for(int x = 0; x < 5; x++) {
                System.out.println("Second");
                if (x == 2)
                    break stop3;
        } 

В случае 2 , когда вы ломаете метку stop3, элемент управления не go возвращается обратно в течение l oop.

1 голос
/ 25 января 2020

В вашем случае вам не нужен помеченный перерыв. в Java оператор break разрывает l oop, который его содержит. Таким образом, ваш stop2 кодовый блок действительно может быть.

for (int x = 0; x < 5; x++) {
    System.out.println("Count");
    if (x == 2) {
        break stop2;
    }
}

Примером помеченного разрыва может быть следующий.

Предположим, что у вас есть oop в пределах oop и какое-то условие, которое вы хотите вырвать из внешнего l oop. Пример:

stop2:
for (int x=0; x < 5; x++) {
  for (int y=0; y<5;y++) {
    if (x == 3 && y == 2)  { //just making up some condition for the example
        break stop2;
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...