usando tags en java sin “bucles”

Siempre pensé que las tags se deben usar solo con bucles, pero parece que no. Dando tal código:

public class LabelTest { public static void main(String[] args) { label1: System.out.println(""); label2: LabelTest t = new LabelTest(); } } 

Cuando se comstack la línea etiquetada “etiqueta1” comstack, pero el código en “etiqueta2” da errores. ¿Porque eso? ¿Y por qué querría etiquetar declaraciones que no son “bucles”?

Se obtiene un error porque una etiqueta no se puede aplicar a las declaraciones de variables, así es como se define la gramática del lenguaje (una etiqueta solo puede preceder a un LocalVariableDeclarationStatement , y un LocalVariableDeclarationStatement no es un LocalVariableDeclarationStatement ). La razón es probablemente que podría causar confusión con respecto al scope variable. Esto funciona:

  label1: System.out.println(""); label2: { LabelTest t = new LabelTest(); } 

Para agregar a la respuesta de Michael Borgwardt, puede hacer cosas como esta por conveniencia (el otro día lo descubrí mientras leía el código fuente Java rt.jar):

 BlockSegment: if (conditionIsTrue) { doSomeProcessing (); if (resultOfProcessingIsFalse()) break BlockSegment; otherwiseDoSomeMoreProcessing(); // These lines get skipped if the break statement // above gets executed } // This is where you resume execution after the break anotherStatement(); 

Ahora, esto es lógicamente equivalente a:

 if (conditionIsTrue) { doSomeProcessing (); if (!resultOfProcessingIsFalse()) { otherwiseDoSomeMoreProcessing(); // More code here that gets executed } } anotherStatement(); 

Pero puede saltear algunas de las llaves adicionales (y las indentaciones que vienen con llaves). Tal vez se vea más limpio (lo hace en mi opinión), y hay algunos lugares donde este estilo de encoding puede ser apropiado y menos confuso.

Entonces, puedes usar tags más allá de los bucles, e incluso más allá de las declaraciones if . Por ejemplo, esta es la syntax de Java válida (y tal vez podría evocar una razón para hacer algo como esto):

 statementOne(); statementTwo(); BlockLabel: { statementThree(); boolean result = statementFour(); if (!result) break BlockLabel; statementFive(); statementSix(); } statementSeven(); 

Si el break se ejecuta aquí, la ejecución se salta al final del bloque indicado por la etiqueta, y se saltan las statementFive() y statementSix() .

La utilidad de este estilo (sin una instrucción if ) se vuelve más evidente cuando tienes bloques dentro de bloques donde debes omitir. En general, puede lograr todo con un uso lo suficientemente inteligente de los bucles. Sin embargo, hay algunos casos en que las tags sin bucles facilitan la lectura del código. Por ejemplo, si necesita verificar secuencialmente los parámetros, puede hacer esto o lanzar una excepción. Termina siendo una cuestión de limpieza de código y estilo personal.

No comstack ¡Buena pregunta! Acabo de jugar un poco con tu fragmento de código. Parece que el comstackdor espera una llamada de método u operador después de la etiqueta. No permite la asignación en este punto.

Creo que el hecho de que la etiqueta no esté prohibida antes de los operadores que no sea para, while y do es probablemente un error (?!) Del comstackdor de Java de especificación. De todos modos, no es tan crítico. No me molesta (personalmente).

La syntax de Java se basa en la syntax de C.

En C puede colocar una etiqueta en cualquier lugar (no solo en los bucles) y luego usar goto para pasar la ejecución a esa línea. Ahora, goto no se implementó en Java, pero las tags se dejaron para que se puedan usar en combinación con break o continue .

No es tan importante ya que este no es un uso estándar de tags de todos modos. Usar tags con continue o break es suficientemente malo (la mayoría de las veces). Usarlos libremente también es inútil.

Consulte Lable en JLS