Cláusulas break e continue rotuladas

Alguém sabe pra que exatamente serve isso? Desde que versão do java isso existe? Qual a diferença dessas cláusulas para as não rotuladas?

public void testaBreak()
    {
    	//break rotulado
    	Outer:
		for(int var1=0; var1 < 5 ; var1++)
		{
		         for(int var2 = 1; var2 < 5; var2++)
		        {
		                System.out.println("var1:" + var1 + ", var2:" + var2);
		
		                if(var1 == 3)
		                {
		                	break Outer;
		                }
		        }
		}
    }
    
    public void testeContinue()
    {
    	Outer:
		for(int var1 =0; var1 < 5 ; var1++)
		{
		
		        for(int var2=0 ; var2 < 5 ; var2++)
		        {
		                if(var2 == 2)
		                {
		                	continue Outer;	
		                }
		                
		                System.out.println("var1:" + var1 + ", var2:" + var2);
		        }
		
		}
    }

Estes são os chamados break e continue rotulados, que funcionam mais ou menos assim:
Quando o programa atinge um break <rótulo>, a iteração identificada por aquele rótulo será interrompida.
No seu exemplo, ao atingir a instrução “break Outer;”, a iteração rotulada com “Outer” será interrompida,
passando o ponteiro de instrução para a próxima instrução após a iteração.
Já o continue <rótulo> faz com que a iteração atual pare e uma nova iteração à partir do rótulo seja iniciada.
No seu exemplo, ao atingir a instrução “continue Outer;”, o ponteiro de instrução passará para a linha “for(int var1 =0; var1 < 5 ; var1++)”,
executando uma nova iteração. Ou seja, o comando “System.out.println(“var1:” + var1 + “, var2:” + var2);” não será executado.

Você pode perceber isso fazendo um debug do código.

As instruções de desvio não rotuladas nas iterações conseguem desviar o fluxo apenas dentro de uma iteração. Ou seja, um comando break
consegue interromper a iteração em que está e um comando continue consegue apenas efetuar uma nova iteração no bloco em que está.
Já as instruções rotuladas, conseguem desviar o fluxo para outros blocos, como no seu exemplo em que o fluxo é desviado
para a iteração mais externa.

E só para completar, isso existe desde o tempo em que o Java não se chamava Java, e sim Oak. Isso foi incluído na linguagem:

  • Porque era simples de implementar;
  • Para evitar um uso de “goto” que é muito freqüente em C e C++ e que é perfeitamente legítimo nessas linguagens.