“Loop:” no código Java. O que é isso e por que ele compila?

113

Este código apenas me fez olhar para minha tela por alguns minutos:

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

( linha 137 aqui )

Nunca tinha visto isso antes e não tinha ideia de que Java tinha uma palavra-chave "loop" (o NetBeans nem mesmo a coloria como uma palavra-chave) e compila bem com o JDK 6.

Qual é a explicação?

Amy B
fonte

Respostas:

205

Não é um keyword, é um label.

Uso:

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

Documentação .

Jigar Joshi
fonte
19
Vale a pena mencionar, como o OP pode não estar familiarizado com o conceito goto / label, que ele geralmente é considerado uma prática ruim, exceto em situações muito particulares (por exemplo, para atalho para vários loops aninhados).
haylem
10
@haylem é verdade, mas eu iria mais longe: vários loops aninhados também são uma prática ruim. Sempre que usei rótulos de loop, acabei refatorando o código para não precisar deles. Sempre existe uma maneira melhor do que essa.
Sean Patrick Floyd
73

Como outros pôsteres já disseram, é um rótulo, não uma palavra-chave. Usar rótulos permite fazer coisas como:

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

Isso permite a quebra do loop externo.

Link para a documentação .

Rob Di Marco
fonte
31

A pergunta foi respondida, mas como uma observação lateral:

Eu ouvi perguntas da entrevista como "Por que este código Java é válido?" (retirou o exemplo mais simples; aqui está o mais mesquinho, obrigado Tim Büthe):

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

Todos vocês sabem o que é esse código (além de horrível)?

Solução: dois rótulos, urle http, um comentário www.myserver.com/myfile.mp3e uma chamada de método com um parâmetro que possui o mesmo nome ( url) do rótulo. Sim, isso compila (se você definir a chamada do método e a variável local em outro lugar).

Sean Patrick Floyd
fonte
Para sua informação, você não precisa do loop, a; na próxima linha é o suficiente
Tim Büthe
Obrigado por me lembrar, acho que não houve loops na pergunta. Vou editar minha resposta (nunca me fizeram essa pergunta, mas o entrevistador era um ex-colega meu)
Sean Patrick Floyd
16

Isso não é uma palavra-chave, é um rótulo. Ele deve ser usado com as palavras break- continuechave e dentro de loops aninhados:

outer:
for(;;){
    inner:
    for(;;){
        if(){
            break inner; // ends inner loop
        } else {
            break outer; // ends outer loop
        }
    }
}
Michael Borgwardt
fonte
inneretiqueta é inútil aqui, break;é o suficiente
gertas
12
Se houver duas maneiras de quebrar o loop, agradeço o innerrótulo para maior clareza.
Steve Jackson
1
@gertas: Acho que ele está apenas demonstrando isso. Mas, de acordo com Steve Jackson, pode ser uma boa ideia dizer isso para fins de autodocumentação de qualquer maneira.
Jay,
5

Não é uma palavra-chave; é um rótulo .

Ele permite que você vá etiquetado breake etiquetado continue.

codadicto
fonte
4

Esta é realmente uma resposta ao comentário de Seanizer sobre a resposta de org.life.java, mas eu queria inserir algum código, então não pude usar o recurso de comentário.

Embora seja muito raro eu encontrar um uso para "quebrar rótulo", isso acontece ocasionalmente. O caso mais comum é quando procuro algo que está em uma estrutura que requer um loop aninhado para pesquisar, como:

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

Normalmente, nesses casos, empurro tudo para uma sub-rotina para que, em um acerto, possa retornar o objeto encontrado e, se ele cair do final do loop, posso retornar null para indicar um não encontrado ou talvez lançar uma exceção. Mas isso é ocasionalmente útil.

Francamente, acho que os inventores do Java incluíram esse recurso porque, entre isso e o tratamento de exceções, eles eliminaram os dois últimos usos legítimos do GOTO.

Adendo muito tarde:

Eu vi uma ótima linha de código uma vez. O programador escreveu:

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

Na verdade, ele não disse "example.com", mas o site da nossa empresa.

Dá a impressão de que existe um URL no código. Compila com sucesso, como se fizesse alguma coisa. Mas o que isso faz?

Na realidade, não faz nada. "http:" é um rótulo ao qual ele nunca faz referência. Então o "//" transforma o resto da linha em um comentário.

Jay
fonte
4

É um rótulo de ponto de interrupção, para permitir que você saia de um loop especificado, ao invés de simplesmente o mais interno em que você está.

É usado na linha 148 .

PaulJWilliams
fonte
2

Você poderia escrever quase qualquer coisa, pois é um rótulo ... Você tem um exemplo aqui

SoulWanderer
fonte
2

É um rótulo, mas veja o seguinte exemplo:

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

Quando b>10o fluxo de execução vai para o loop externo.

Alberto Zaccagni
fonte
1

É um rótulo e os rótulos em Java podem ser usados ​​com as palavras-chave breake continuepara controle adicional sobre os loops.

Aqui está explicado de uma maneira bastante boa:

Pensando em Java, pare e continue

vstoyanov
fonte
1

Não é uma palavra-chave, mas um rótulo . Se estiver dentro do forloop, você escreve break loop;e sai desse loop.

Greuze
fonte
0

É um rótulo. Geralmente, um rótulo usado em Java para transferir o fluxo de controle no local desejado, enquanto todas as palavras-chave, como continue e break, têm uma escolha especificada de local.

RTA
fonte