W3docs

Sentencias etiquetadas en Java

Usa etiquetas en Java para hacer break o continue en bucles externos desde dentro de bucles anidados.

Un break simple sale del bucle más interno y un continue simple omite una iteración del mismo. Cuando estás dentro de bucles anidados y necesitas controlar el bucle externo desde el interno, Java te ofrece las sentencias etiquetadas: un nombre que puedes asociar a un bucle, y un break o continue que lo apunta por ese nombre.

Este capítulo cubre cómo definir una etiqueta, cómo el break y continue etiquetados cambian el flujo, cuándo usarlos (raramente) y las alternativas más claras que deberías considerar primero.

Esto es lo más parecido que tiene Java a goto — y está intencionalmente limitado a bucles (y switch).

Definir una etiqueta

Una etiqueta es un identificador seguido de dos puntos, colocado inmediatamente antes de un bucle:

outer:
for (int i = 0; i < 5; i++) {
  // ...
}

El nombre (outer aquí) sigue las mismas reglas que cualquier identificador Java. No es obligatorio llamarlo outersearchLoop, rows, cualquier nombre válido funciona. Elige un nombre que indique por qué está la etiqueta.

break etiquetado

break <label>; sale del bucle marcado con esa etiqueta, sin importar cuán profundamente anidado estés dentro de él:

int[][] grid = {
  {1, 2, 3},
  {4, 5, 6},
  {7, 8, 9}
};
int target = 5;
int foundRow = -1, foundCol = -1;

search:
for (int r = 0; r < grid.length; r++) {
  for (int c = 0; c < grid[r].length; c++) {
    if (grid[r][c] == target) {
      foundRow = r;
      foundCol = c;
      break search;
    }
  }
}
System.out.println("found at " + foundRow + "," + foundCol);

Sin el break etiquetado, necesitarías una variable bandera o reestructurar el código. Con él, sales de ambos bucles a la vez en el momento en que se encuentra el objetivo.

continue etiquetado

continue <label>; omite el resto de ambas la iteración interna actual y continúa con la siguiente iteración del bucle externo etiquetado:

rowLoop:
for (int r = 0; r < grid.length; r++) {
  for (int c = 0; c < grid[r].length; c++) {
    if (grid[r][c] < 0) {
      continue rowLoop;     // skip the rest of this row
    }
    process(grid[r][c]);
  }
}

Cuando el bucle interno encuentra un valor negativo, se omite el resto de esa fila y se continúa con la siguiente.

Úsalos con moderación

Las etiquetas funcionan, pero es fácil abusar de ellas. Siempre que vayas a usar una, considera primero las alternativas:

  • Extrae un método auxiliar. Dentro de un método, un return simple sale de todos los bucles a la vez y suele ser más claro:

    static int[] find(int[][] grid, int target) {
      for (int r = 0; r < grid.length; r++) {
        for (int c = 0; c < grid[r].length; c++) {
          if (grid[r][c] == target) return new int[]{r, c};
        }
      }
      return null;
    }
  • Usa una bandera — un poco menos limpio pero explícito y sin goto:

    boolean found = false;
    for (int r = 0; !found && r < grid.length; r++) {
      for (int c = 0; c < grid[r].length; c++) {
        if (grid[r][c] == target) { found = true; break; }
      }
    }
  • Usa streams para problemas de filtrado en lugar de bucles anidados.

Recurre a las etiquetas cuando las alternativas realmente perjudican la legibilidad — típicamente con dos o tres niveles de profundidad y con una intención clara de "abortar la búsqueda" o "siguiente iteración externa".

Etiquetas y switch

Las etiquetas también funcionan con switch, aunque es poco frecuente:

sw:
switch (cmd) {
  case "x":
    if (someCondition) break sw;
    // ...
    break;
}

En la práctica, esto nunca aporta más claridad que un break simple.

Un ejemplo práctico

java— editable, runs on the server

Qué sigue

Has terminado los capítulos de flujo de control: condicionales, el operador ternario, switch, bucles y las sentencias que los interrumpen. A continuación viene la parte sobre métodos — cómo empaquetar bloques de código para poder invocarlos por nombre.

Práctica

Práctica
¿Qué hace un break etiquetado?
¿Qué hace un break etiquetado?
Was this page helpful?