break, continue와 레이블
반복문의 기본 조건만으로 흐름을 표현하기 어려울 때 break와 continue가 보조 경로를 만듭니다.
break는 현재 반복을 끝내고 continue는 현재 회차의 나머지를 건너뜁니다.
중첩 반복에서는 기본적으로 가장 안쪽 반복에만 영향을 줍니다.
Java의 레이블은 바깥 반복을 직접 지정할 수 있지만 흐름이 멀리 이동해 읽기 비용이 커질 수 있습니다.
여기서는 조기 종료가 의도를 선명하게 하는 경우와 메서드 분리가 나은 경우를 나눕니다.
break는 더 찾을 이유가 없을 때 쓴다
검색 결과 하나만 필요하거나 종료 신호를 만났을 때 뒤 원소를 처리하지 않습니다.
찾았는지 나타내는 상태 변수와 함께 쓰면 반복 뒤 결과를 설명하기 쉽습니다.
continue는 예외 입력을 먼저 걸러 낸다
유효하지 않은 원소를 초반에 건너뛰면 정상 처리의 들여쓰기를 줄일 수 있습니다.
여러 continue가 흩어지면 어떤 원소가 제외됐는지 추적하기 어려워집니다.
음수나 손상된 입력을 루프 앞부분에서 continue로 넘기면 정상 처리의 핵심이 깊게 중첩되지 않습니다. 다만 건너뛴 원소도 반복 상태 갱신이 필요한 구조라면 갱신보다 앞에서 continue하지 않았는지 확인해야 합니다.
public class LoopControl {
public static void main(String[] args) {
int[][] grid = {{1, 3}, {5, 8}, {13, 21}};
int target = 8;
int foundRow = -1;
outer:
for (int row = 0; row < grid.length; row++) {
for (int value : grid[row]) {
if (value % 2 != 0) continue;
if (value == target) {
foundRow = row;
break outer;
}
}
}
System.out.println("row=" + foundRow);
}
}target을 홀수인 21로 바꾸면 값이 배열에 있어도 앞의 continue에서 제외되어 결과가 -1로 남습니다. “짝수만 검색한다”가 요구 사항이 아니라면 일치 검사보다 필터를 먼저 둔 순서가 잘못된 것이므로, 조건 순서 역시 프로그램의 계약임을 알 수 있습니다.
row=1continue는 홀수를 제외하고 레이블 break는 목표를 찾은 즉시 두 반복을 함께 끝냅니다.
현재 원소가 처리 대상이 아니면 다음 반복으로 이동합니다. 반복 변수 갱신이 본문 끝에 있다면 건너뛰어도 종료가 보장되는지 함께 확인합니다.
정상 원소만 남은 본문에서 필요한 계산이나 좌표 저장을 수행합니다. 검색 결과 하나만 필요하다면 찾은 직후 더 순회할 이유가 없습니다.
중첩 탐색에서는 break outer로 바깥 반복까지 종료합니다. 바깥 루프의 뒤 작업도 실행하지 않아야 한다면 탐색을 메서드로 추출해 return하는 선택도 비교합니다.
레이블은 중첩 루프의 대상을 지정한다
break outer는 이름 붙은 바깥 반복까지 끝냅니다.
두 단계 이상의 중첩을 벗어나야 할 때 쓸 수 있지만 별도 메서드와 return이 더 읽기 쉬운지 비교합니다.
레이블이 붙은 break outer는 가장 가까운 루프가 아니라 이름 붙인 바깥 루프를 끝냅니다. 2차원 탐색에서 첫 일치 좌표만 필요할 때는 유용하지만, 레이블 사이 거리가 길어지면 탐색을 메서드로 추출해 return하는 편이 흐름을 따라가기 쉽습니다.
for (String value : java.util.List.of("", "java", "stop", "after")) {
if (value.isBlank()) continue; // 빈 값만 건너뜀
if (value.equals("stop")) break; // 현재 반복 종료
System.out.println(value);
}// 레이블이 멀리 떨어지거나 여러 개면 메서드 추출을 검토한다.흐름 이동 거리를 짧게 유지한다
제어문과 대상 위치가 멀수록 독자가 사이 코드를 모두 확인해야 합니다.
조기 종료가 핵심 경로를 단순하게 만들 때만 사용합니다.
스트림이나 메서드 추출이 더 나은지 비교한다
검색과 필터링만 필요한 반복은 컬렉션 API로 의도를 표현할 수 있습니다.
복잡한 상태 기계라면 명시적 반복문이 오히려 이해하기 쉽습니다.
스트림은 “조건에 맞는 첫 원소”처럼 변환 의도가 선명할 때 좋고, 중첩 인덱스나 여러 상태를 함께 갱신할 때는 반복문이 더 직접적일 수 있습니다. 문법 길이보다 종료 지점과 상태 변경이 한눈에 보이는 쪽을 선택합니다.
break와 continue는 반복 조건을 대신하는 장치가 아니라 드문 조기 종료와 제외 규칙을 가까이 표현하는 장치입니다.