Eu já sou um defensor dos “labeled loops” (quando usados com critério, é lógico).
Eles evitam o único uso “legítimo” do “goto” em C# e C++, que é exatamente esse.
A única coisa que não gostei nos labeled loops é que eles não são muito intuitivos no caso do “break”.
Se eu não houvesse lido a especificação da linguagem, pensaria que um break, para sair de 2 níveis de loops, seria assim:
for (....) {
for (....) {
if (.....)
break caifora;
}
}
caifora:
porque você vê explicitamente que o break vai para esse lugar chamado “caifora”.
Mas em Java, para você sair de 2 níveis de loops, você precisa fazer assim:
caifora:
for (....) {
for (....) {
if (.....)
break caifora;
}
}
Isso, obviamente, não é nem um pouco intuitivo.
Funciona bem para o “continue” (que é uma espécie de “goto para trás”) mas não para o “break” (que é um “goto para frente”).
Na verdade, quando preciso fazer isso, normalmente indico, em um comentário, que o “break caifora” cai fora do for mais externo, apenas para evitar que alguém que esteja mantendo meu programa e não conheça essas sutilezas da linguagem acabe estragando tudo.