«Цикл:» в коде Java. Что это такое и почему он компилируется?

113

Этот код просто заставил меня на несколько минут уставиться на свой экран:

loop:
for (;;) {
    // ...
}

( здесь строка 137 )

Я никогда не видел этого раньше и понятия не имел, что в Java есть ключевое слово loop (NetBeans даже не раскрашивает его как ключевое слово), и он прекрасно компилируется с JDK 6.

Какое объяснение?

Эми Б
источник

Ответы:

205

Это не keyworda label.

Использование:

    label1:
    for (; ; ) {
        label2:
        for (; ; ) {
            if (condition1) {
                // break outer loop
                break label1;
            }
            if (condition2) {
                // break inner loop
                break label2;
            }
            if (condition3) {
                // break inner loop
                break;
            }
        }
    }

Документация .

Джигар Джоши
источник
19
Стоит упомянуть, что, поскольку OP может быть не знаком с концепцией goto / label, это обычно считается плохой практикой, за исключением очень конкретных ситуаций (например, для сокращения нескольких вложенных циклов).
haylem
10
@haylem правда, но я бы пошел дальше: множественные вложенные циклы тоже обычно плохая практика. Всякий раз, когда я использовал метки цикла, я в конце концов реорганизовал код, чтобы они мне не понадобились. Всегда есть способ лучше.
Шон Патрик Флойд,
73

Как говорили другие плакаты, это ярлык, а не ключевое слово. Использование ярлыков позволяет делать такие вещи, как:

outer: for(;;) {
   inner: for(;;) {
     break outer;
   }
}

Это позволяет разорвать внешний цикл.

Ссылка на документацию .

Роб Ди Марко
источник
31

На вопрос дан ответ, но в качестве примечания:

Я слышал о вопросах собеседования типа «Почему этот код Java действителен?» (удалил более простой пример; вот более злой, спасибо Тиму Бюту):

url: http://www.myserver.com/myfile.mp3
downLoad(url);

Вы все знали бы, что это за код (кроме ужасного)?

Решение: две метки, urlи http, комментарий www.myserver.com/myfile.mp3и вызов метода с параметром, имя которого ( url) совпадает с именем метки. Да, это компилируется (если вы определяете вызов метода и локальную переменную в другом месте).

Шон Патрик Флойд
источник
К вашему сведению, вам не нужен цикл, a; в следующей строке достаточно
Тим Бют
Спасибо, что напомнили, думаю, в вопросе не было петель. Я отредактирую свой ответ (мне никогда не задавали этот вопрос, но интервьюером был мой бывший коллега)
Шон Патрик Флойд,
16

Это не ключевое слово, это ярлык. Это предназначено для использования с breakи continueключевыми словами внутри вложенных циклов:

outer:
for(;;){
    inner:
    for(;;){
        if(){
            break inner; // ends inner loop
        } else {
            break outer; // ends outer loop
        }
    }
}
Майкл Боргвардт
источник
innerярлык здесь бесполезен, break;достаточно
gertas
12
Если есть два способа разорвать петлю, я ценю innerэтикетку за ясность.
Стив Джексон,
1
@gertas: Думаю, он просто демонстрирует суть. Но, по мнению Стива Джексона, в любом случае было бы неплохо сказать это для самостоятельной документации.
Джей
5

Это не ключевое слово; это ярлык .

Это позволяет вам идти помеченным breakи помеченным continue.

codaddict
источник
4

Это действительно ответ на комментарий seanizer к ответу org.life.java, но я хотел вставить некоторый код, чтобы я не мог использовать функцию комментариев.

Хотя я очень редко нахожу использование для «разрыва ярлыка», иногда это случается. Самый распространенный случай - это когда я ищу что-то, что находится в структуре, требующей для поиска вложенного цикла, например:

search:
for (State state : stateList)
{
  for (City city : state.cityList)
  {
    if (city.zipcode.equals(wantZip))
    {
      doSomethingTo(city);
      break search;
    }
  }
}

Обычно в таких случаях я помещаю все это в подпрограмму, чтобы при попадании я мог вернуть найденный объект, а если он выпадает в нижней части цикла, я могу вернуть null, чтобы указать, что он не найден, или, возможно, выбросить исключение. Но иногда это бывает полезно.

Откровенно говоря, я думаю, что изобретатели Java включили эту функцию, потому что между этим и обработкой исключений они устранили последние два законных использования GOTO.

Очень позднее приложение:

Однажды я увидел отличную строчку кода. Программист написал:

http://www.example.com/xyz.jsp
for (Foo foo1 : foolist)

На самом деле он сказал не example.com, а веб-сайт нашей компании.

Создается впечатление, что в коде есть URL. Он успешно компилируется, как будто что-то делает. Но ... что он делает?

На самом деле ничего не делает. «http:» - это ярлык, на который он никогда не ссылается. Затем "//" делает оставшуюся часть строки комментарием.

Джей
источник
4

Это метка точки останова, которая позволяет вам выйти из указанного цикла, а не просто самого внутреннего цикла, в котором вы оказались.

Он используется в строке 148 .

PaulJWilliams
источник
2

Вы могли бы написать что угодно, как это ярлык ... У вас есть пример здесь

ДушаСтранник
источник
2

Это ярлык, хотя посмотрите на следующий пример:

int a = 0;
int b = 0
while (a<10){
    firstLoop:
    a++;
    while(true){
        b++
        if(b>10){
            break firstLoop;
        }
    }
 }

Когда b>10поток выполнения переходит во внешний цикл.

Альберто Дзакканьи
источник
1

Это метка, и метко в Java можно использовать с breakи continueключевыми словами для дополнительного контроля над петлями.

Здесь это объясняется довольно хорошо:

Думая на Java, сломай и продолжай

встоянов
источник
1

Это не ключевое слово, а ярлык . Если внутри forцикла вы пишете break loop;, и вы выходите из этого цикла.

Греза
источник
0

Это ярлык. Обычно метка, используемая в Java для передачи потока управления в желаемое место, в то время как все ключевые слова, такие как continue и break, имеют указанный выбор местоположения.

RTA
источник