導入
Javaでのプログラミングにおいて、多重ループ(入れ子になったfor文やwhile文)から抜け出したり、特定の処理をスキップしたりするケースは頻繁に発生します。通常のbreakやcontinueは「直近のループ」にしか影響しませんが、Labeled continue(ラベル付きcontinue)を活用することで、外側のループを直接制御し、可読性と効率を両立させることができます。本稿では、レガシーな制御フローから、モダンなJava(Java 17以降)の機能を組み合わせた効率的なコーディング手法を解説します。
基礎知識
Labeled continueとは、ループ文の直前に「ラベル名:」を付与し、内側のループからそのラベルを指定してcontinueを行う仕組みです。
- 通常のcontinue: 直近のループの次の反復へ移行。
- Labeled continue: 指定したラベルの外側ループの次の反復へ移行。
同様の概念でbreakを使うことも可能ですが、continueと組み合わせることで「特定の条件を満たした場合だけ、外側のループまで戻って次の要素を処理する」といった複雑なロジックを簡潔に表現できます。また、Java 14以降で導入されたswitch expressionsやyield、sealed classesといった現代的な制御構文を組み合わせることで、エラーの少ない堅牢なコードが書けます。
実装/解決策
多重ループの中で「条件を満たしたとき、現在の内側ループを中断し、外側のループの次のインデックスへ進みたい」という場合、フラグ変数(boolean)を多用しがちです。しかし、フラグ管理はバグの温床となります。ここでLabeled continueを使用すれば、フラグなしで直感的な制御が可能です。
サンプルプログラム
以下のコードは、二次元配列から特定の条件に合致する要素を探し、見つかった場合は外側ループの次の要素へスキップする例です。
public class LoopControlExample {
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 外側のループにラベルを付与
outerLoop:
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
int value = matrix[i][j];
// 5という数値が見つかったら、外側ループの次の行へジャンプ
if (value == 5) {
System.out.println("5を発見!行をスキップします。");
continue outerLoop;
}
System.out.println("処理中: " + value);
}
}
}
}
応用・注意点
1. 過度な利用の回避: Labeled continueは強力ですが、多用しすぎると「スパゲッティコード」の原因となります。コードが複雑になりすぎる場合は、メソッドを分割してreturnで抜ける設計を検討してください。
2. モダン機能との併用: 現代的なJava開発では、複雑なループを避けるためにStream APIを活用するのが推奨されます。しかし、パフォーマンスが極めて重要な低レイヤー処理や、特定のアルゴリズム実装ではLabeled continueが最適解となることもあります。
3. Sealed Classesとの組み合わせ: switch expressionsで処理分岐を行う際、sealed classesを使用すると、網羅性が保証されます。ループ処理の結果をswitchで受け取り、yieldで値を返すような設計にすることで、より宣言的で安全なコードになります。
現場のシニアエンジニアとしては、単に「動くコード」ではなく、「後続のエンジニアが論理を追いやすいコード」を意識してください。ラベル命名には、そのループが何をしているのか(例: outerProcess, rowLoop)を明示的に記述するのがコツです。

コメント