¿Debo evitar el uso de Instrucciones de Etiquetas Java?


Hoy tuve un compañero de trabajo sugerir refactorizar mi código para usar una declaración de etiqueta para controlar el flujo a través de 2 anidados para bucles que había creado. Nunca los he usado antes porque personalmente creo que disminuyen la legibilidad de un programa. Sin embargo, estoy dispuesto a cambiar de opinión sobre su uso si el argumento es lo suficientemente sólido. ¿Cuáles son las opiniones de la gente sobre las declaraciones de etiquetas?

 66
Author: Willmore, 2008-09-05

11 answers

Muchos algoritmos se expresan más fácilmente si puede saltar a través de dos bucles (o un bucle que contiene una instrucción switch). No te sientas mal por eso. Por otro lado, puede indicar una solución demasiado compleja. Así que retrocedan y miren el problema.

Algunas personas prefieren un enfoque de "entrada única, salida única" para todos los bucles. Es decir, evitar la ruptura (y continuar) y el retorno temprano de los bucles por completo. Esto puede resultar en algún código duplicado.

Lo que evitaría fuertemente hacer es introducir variables auxiliares. Ocultar el flujo de control dentro del estado aumenta la confusión.

Dividir los bucles etiquetados en dos métodos bien puede ser difícil. Las excepciones son probablemente demasiado pesadas. Intente una sola entrada, una sola salida.

 49
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-05 19:03:10

Las etiquetas son como las de goto: Úsalas con moderación, y solo cuando hacen que tu código sea más rápido y más importante, más comprensible,

Por ejemplo, si estás en bucles grandes de seis niveles de profundidad y te encuentras con una condición que hace que el resto del bucle no tenga sentido completar, no tiene sentido tener 6 puertas trampa adicionales en tus declaraciones de condición para salir del bucle temprano.

Las etiquetas (y goto) no son malas, es solo que a veces la gente las usa en malas formas. La mayoría de las veces estamos realmente tratando de escribir nuestro código por lo que es comprensible para usted y el próximo programador que viene. Hacerlo súper rápido es una preocupación secundaria (tenga cuidado con la optimización prematura).

Cuando las etiquetas (y goto) son mal utilizadas hacen que el código sea menos legible, lo que causa dolor para usted y el siguiente desarrollador. Al compilador no le importa.

 32
Author: BIBD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-08 18:16:44

Hay pocas ocasiones en las que necesite etiquetas y pueden ser confusas porque rara vez se usan. Sin embargo, si necesita usar uno, use uno.

POR cierto: esto compila y se ejecuta.

class MyFirstJavaProg {  
        public static void main(String args[]) {
           http://www.javacoffeebreak.com/java101/java101.html
           System.out.println("Hello World!");
        }
}
 27
Author: Peter Lawrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-15 12:51:39

Tengo curiosidad por saber cuál es su alternativa a las etiquetas. Creo que esto se va a reducir al argumento de " return as early as possible "vs." use una variable para mantener el valor de retorno, y solo regrese al final."

Las etiquetas son bastante estándar cuando tiene bucles anidados. La única manera en que realmente disminuyen la legibilidad es cuando otro desarrollador nunca los ha visto antes y no entiende lo que significan.

 8
Author: Outlaw Programmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-05 18:38:24

Nunca he visto etiquetas usadas "in the wild" en código Java. Si realmente desea romper a través de bucles anidados, vea si puede refactorizar su método para que una sentencia early return haga lo que desea.

Técnicamente, supongo que no hay mucha diferencia entre un regreso temprano y una etiqueta. Prácticamente, sin embargo, casi todos los desarrolladores de Java ha visto un regreso temprano y sabe lo que hace. Supongo que muchos desarrolladores al menos se sorprenderían por una etiqueta, y probablemente confundir.

Me enseñaron la ortodoxia de entrada única / salida única en la escuela, pero desde entonces he llegado a apreciar las declaraciones de retorno temprano y la ruptura de bucles como una forma de simplificar el código y hacerlo más claro.

 5
Author: Don Kirkby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-05 21:17:20

Argumentaría a favor de ellos en algunos lugares, los encontré particularmente útiles en este ejemplo:


nextItem: for(CartItem item : user.getCart()) {

  nextCondition : for(PurchaseCondition cond : item.getConditions()) {
     if(!cond.check())
        continue nextItem;
     else
        continue nextCondition;

  }
  purchasedItems.add(item);
}
 5
Author: Ceilingfish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-26 12:26:39

Creo que con el nuevo bucle for-each, la etiqueta puede ser muy clara.

Por ejemplo:

sentence: for(Sentence sentence: paragraph) {
  for(String word: sentence) {
    // do something
    if(isDone()) {
      continue sentence;
    }
  }
}

Creo que eso se ve muy claro al tener su etiqueta igual que su variable en el nuevo para-cada uno. De hecho, tal vez Java debería ser malo y añadir etiquetas implícitas para-cada variables heh

 5
Author: Pyrolistical,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-13 21:02:58

He utilizado un bucle etiquetado Java para una implementación de un método Sieve para encontrar números primos (hecho para uno de los problemas matemáticos del proyecto Euler) que lo hizo 10 veces más rápido en comparación con los bucles anidados. Por ejemplo, si (cierta condición) volver al bucle exterior.

private static void testByFactoring() {
    primes: for (int ctr = 0; ctr < m_toFactor.length; ctr++) {
        int toTest = m_toFactor[ctr];
        for (int ctr2 = 0; ctr2 < m_divisors.length; ctr2++) {
            // max (int) Math.sqrt(m_numberToTest) + 1 iterations
            if (toTest != m_divisors[ctr2]
                        && toTest % m_divisors[ctr2] == 0) {
                continue primes; 
            }
        } // end of the divisor loop
    } // end of primes loop
} // method

Le pregunté a un programador de C++ qué tan malos son los bucles etiquetados, dijo que los usaría con moderación, pero ocasionalmente pueden ser útiles. Por ejemplo, si tiene 3 bucles anidados y para ciertas condiciones desea volver a la bucle externo.

Así que tienen sus usos, depende del problema que estabas tratando de resolver.

 5
Author: Selenia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-26 12:54:06

Nunca uso etiquetas en mi código. Prefiero crear un guardia e inicializarlo a null u otro valor inusual. Este protector es a menudo un objeto resultado. No he visto a ninguno de mis compañeros de trabajo usando etiquetas, ni he encontrado ninguna en nuestro repositorio. Realmente depende de su estilo de codificación. En mi opinión, el uso de etiquetas disminuiría la legibilidad, ya que no es una construcción común y por lo general no se utiliza en Java.

 3
Author: Bartosz Bierkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-05 18:43:36

Sí, debe evitar usar label a menos que haya una razón específica para usarlos (el ejemplo de simplificar la implementación de un algoritmo es pertinente). En tal caso, yo aconsejaría agregar suficientes comentarios u otra documentación para explicar el razonamiento detrás de él para que alguien no venga más tarde y lo destroce de alguna noción de "mejorar el código" o "deshacerse del olor del código" o alguna otra excusa potencialmente BS.

Equipararía este tipo de pregunta con decidir cuándo se debe o no usar el ternario si. La razón principal es que puede impedir la legibilidad y, a menos que el programador tenga mucho cuidado de nombrar las cosas de una manera razonable, el uso de convenciones como las etiquetas podría empeorar las cosas. Supongamos que el ejemplo usando 'nextCondition' y 'nextItem' había usado 'loop1' y 'loop2' para sus nombres de etiqueta.

Personalmente las etiquetas son una de esas características que no tienen mucho sentido para mí, fuera del Montaje o BÁSICO y otros idiomas similarmente limitados. Java tiene muchas construcciones de bucle y control más convencionales/regulares.

 1
Author: Jeremy Harton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-10 03:44:17

Encontré que las etiquetas a veces son útiles en las pruebas, para separar la configuración habitual, ejercer y verificar fases y declaraciones relacionadas con el grupo. Por ejemplo, usando la terminología BDD:

@Test
public void should_Clear_Cached_Element() throws Exception {
    given: {
        elementStream = defaultStream();
        elementStream.readElement();
        Assume.assumeNotNull(elementStream.lastRead());
    }
    when:
        elementStream.clearLast();
    then:
        assertThat(elementStream.lastRead()).isEmpty();
}

Sus opciones de formato pueden variar, pero la idea central es que las etiquetas, en este caso, proporcionan una distinción notable entre las secciones lógicas que componen su prueba, mejor que los comentarios. Creo que la biblioteca Spock simplemente se basa en esta característica para declarar sus fases de prueba.

 0
Author: polaretto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-11 13:48:59