Javaのcontinue文とは?仕組み・breakとの違い・無限ループ回避を実務解説
CONTENTS
Javaの学習を進めると、for や while のループ制御で登場する continue 文に必ず出会います。しかし、多くの初学者が次のような疑問を抱くのも事実です。
「break とは何が違うの?」
「if 文の else でスキップするのと、どっちが良いの?」
「多重ループの中だと、どこまでスキップされる?」
このような疑問を持つのは当然です。continue は、使い方を間違えると可読性を下げる原因にもなるからです。しかし、正しく使えば「ネスト(入れ子)を浅くし、コードを劇的に読みやすくする」強力な武器になります。
そこで本記事では、Javaの continue 文の基本的な挙動から、実務で頻出する「ガード節」としての活用法、そしてやりがちな「無限ループの落とし穴」までを体系的に解説します。
continue文の基本:処理をスキップして次へ進む
まず、continue 文の役割を一言で表すと、「現在の周(イテレーション)の残りの処理を無視して、即座に次のループへ進む」ための命令です。
例えば、for 文の中で特定の条件(不要なデータなど)に合致した場合、それ以降の重い処理を行わずに次のデータへ移りたいときに利用します。
基本的なコード例(for文)
例えば、「1〜5の数字のうち、3だけスキップして表示したい」という単純なケースを見てみましょう。
for (int i = 1; i <= 5; i++) {
// iが3のときだけ、これ以降の処理を飛ばして次のループへ
if (i == 3) {
continue;
}
System.out.println("現在の数字: " + i);
}
実行結果:
現在の数字: 1
現在の数字: 2
現在の数字: 4
現在の数字: 5
このように、i == 3 のときだけ System.out.println が実行されず、ループの先頭(更新式 i++)に戻っていることが分かります。
【重要】break文との決定的な違い
しかし、学習時によく混同されるのが break 文です。どちらもループの流れを変える制御構文ですが、その影響範囲は明確に異なります。
以下の表で違いを整理しました。
| 構文 | 動作イメージ | 主な利用シーン |
|---|---|---|
| continue | 「今回はパス」。 今の周だけ中断し、次の周を開始する。 |
無効データや対象外データのスキップ。 特定条件の除外。 |
| break | 「ここで解散」。 ループ自体を完全に終了し、外へ抜ける。 |
検索で見つかった時点で終了したい場合。 これ以上処理する必要がない場合。 |
つまり、「まだループを続けたいかどうか」が使い分けのポイントです。リストを最後まで確認する必要があるなら continue、途中で切り上げて良いなら break を選びます。
落とし穴:while文でのcontinueと無限ループ
一方で、while 文や do-while 文で continue を使う場合は、細心の注意が必要です。これが本記事で最も注意してほしいポイントです。
なぜなら、for 文と異なり、while 文では「変数の更新(インクリメントなど)」をプログラマが自分で書く必要があるからです。
例えば、以下のコードは「無限ループ」になり、プログラムが停止しなくなります。
int i = 0;
while (i < 5) {
if (i == 2) {
System.out.println("スキップします");
continue; // ⚠️ ここで戻ると i++ が実行されない!
}
System.out.println(i);
i++; // 更新処理
}
解説:
i が 2 になったとき、continue が実行されると、処理は while (i < 5) の条件判定に戻ります。しかし、i++ は continue の後にあるため実行されず、i は永遠に 2 のままです。その結果、無限に「スキップします」と出力され続けます。
そのため、while 文で使う場合は、必ず continue の前で更新処理を行うか、そもそも for 文への書き換えを検討してください。
参考リンク:Oracle Java Tutorials - Branching Statements
実務での活用:ガード節によるネスト解消
さらに、実務レベルで continue が最も輝くのは、「ガード節(Guard Clause)」として使うパターンです。
ガード節とは、異常系や対象外の条件を関数の先頭(ループの先頭)で判定し、早期にリターン(またはスキップ)させる手法です。これにより、深いネスト(インデント)を防ぐことができます。
悪い例:if-elseのネストが深い
for (User user : userList) {
if (user != null) {
if (user.isActive()) {
if (user.hasEmail()) {
// 📩 ここでようやくメール送信処理
sendMail(user);
}
}
}
}
このように条件が増えると、主要な処理が右側に押しやられ、非常に読みづらくなります。
良い例:continueで早期スキップ
for (User user : userList) {
// ガード節1:nullならスキップ
if (user == null) continue;
// ガード節2:無効ユーザーならスキップ
if (!user.isActive()) continue;
// ガード節3:メアドなしならスキップ
if (!user.hasEmail()) continue;
// 📩 メール送信処理(インデントが浅い!)
sendMail(user);
}
このように continue を使うことで、「処理するための前提条件」と「メインの処理」が明確に分離され、可読性が大幅に向上します。
ラベル付きcontinueの仕組みと是非
Javaには「ラベル付きcontinue」という機能もあります。これは、ネストされた(二重、三重の)ループの内側から、一気に外側のループへスキップしたい場合に使います。
outerLoop: // ラベル
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) {
// 内側のループではなく、外側のloop(i)の更新へ飛ぶ
continue outerLoop;
}
System.out.println("i=" + i + ", j=" + j);
}
}
一見便利に見えますが、多くの開発現場では「原則使用禁止」または「非推奨」とされることが多いです。
その理由は、処理の流れが行ったり来たりして複雑になりやすく(いわゆるスパゲッティコード)、バグの温床になるからです。ラベルを使いたくなった場合は、「メソッドに切り出す」など、設計自体の見直しを推奨します。
参考リンク:Code Conventions for the Java Programming Language
まとめ:continueを使いこなしてクリーンなコードを
本記事では、Javaの continue 文について解説しました。要点を振り返りましょう。
- 基本機能:現在の周をスキップし、次のループへ進む
- breakとの違い:
breakはループからの脱出、continueはループの継続 - 最大の注意点:
while文では更新式がスキップされ、無限ループになるリスクがある - ベストプラクティス:ネストを解消するための「ガード節」として使うのが最も効果的
さらに、Java 8以降では Stream API の filter() メソッドを使うことで、continue を使わずに同様の処理を書くことも一般的になっています。
文法を知っているだけでなく、「どの書き方がチームにとって読みやすいか」を判断できることが、脱初心者への第一歩です。ぜひ実際のコードで、ネストの深い部分を continue でリファクタリングしてみてください。
もし、「自分の書いたコードが良い設計なのか自信がない」「もっと現場レベルの書き方を知りたい」と感じた場合は、プロのエンジニアから直接フィードバックを受ける学習方法が最も効率的です。
つまずいたら、現役エンジニアと一緒に解決しよう
この記事で扱った【Java】は、独学だと細部で詰まりやすい分野です。さらに理解を深めたい方は、Zerocode Onlineで実務直結の学習を進めてみませんか。
コード添削・詰まり解消を丁寧にサポート。
Java/SQL/Spring Bootを体系的に習得。
現場で刺さる成果物づくりを伴走。
時間と場所を選ばず学べます。