站長阿川

站長阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

站長精心設計,帶你實作 63 個小專案,得到作品集!

立即開始免費試讀!

前言

首先,「無限迴圈=壞」並不正確!!
在遊戲的指令等待、伺服器的接收、UI的事件等待等場合,
有很多處理需要持續運行。

重要的是,安全停止的機制運行方式的設計
本文將總結如何以“安全的方式”使用 while(true) 的技巧,
以及 break / continue / 帶標籤的 break


🎓 無限迴圈是什麼?

while (true) {
    // 持續重複
}
  • 目的:持續待命、持續監視、持續繪製等。
  • 關鍵:隨時可以終止的 結束條件 和不會失控的 節制(睡眠或阻塞 IO)

🔧 正確的運行方式(設計模式)

  1. 使用旗標管理

    boolean running = true;
    while (running) {
    String cmd = nextCommand(); // 等待輸入(阻塞)
    if (cmd == null) break;      // EOF 等等
    if (cmd.isBlank()) continue; // 跳過空輸入
    if (cmd.equals("quit")) running = false; // 下一輪退出
    handle(cmd);
    }
  2. 使用監視計數器作為保險

    int guard = 10_000; // 防止過多迴圈
    while (condition && guard-- > 0) {
    // ...
    }

    guard 是「最多可以迴圈幾次」的上限。
    guard-- > 0 的意思是「判斷當前 guard 是否大於 0,然後在判斷之後減 1」 (後置遞減)。

  3. 設置超時

    long deadline = System.currentTimeMillis() + 5_000; // 最多 5 秒
    while (!ready() && System.currentTimeMillis() < deadline) {
    try {
        Thread.sleep(50);
    } catch (InterruptedException ignored) {}
    }
    if (!ready()) System.out.println("超時");
  4. 讓 CPU 休息(不進行自旋)

    while (queue.isEmpty()) {
    try {
        Thread.sleep(10);
    } catch (InterruptedException ignored) {}
    }
    // 或者使用阻塞 API
    // Message msg = queue.take(); // 直到取出為止阻塞

⚡ 指令迴圈(用 quit 結束)

import java.util.Scanner;

public class CommandLoop {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.print("> ");
            String cmd = sc.nextLine().trim();
            if (cmd.isEmpty()) continue;       // 如果沒有輸入,則跳至下一個
            if (cmd.equals("quit")) break;     // 這裡退出
            if (cmd.equals("heal")) heal();    
            else System.out.println("未知指令: " + cmd);
        }
        System.out.println("再見!");
    }
    static void heal() { System.out.println("皮卡丘已經恢復精力!"); }
}

重點:continue 是“跳過本輪剩餘部分”,break 是“跳出整個迴圈”。


🧭 帶標籤的 break:一次性退出多重迴圈(while 版)

Java 的標籤是 位於語句前的識別符 + 冒號 的形式。在搜尋類型的情況下特別方便。

int H = 10, W = 10;
int[][] cave = new int[H][W]; // 0: 通道, 1: 野生寶可夢
cave[4][7] = 1;               // 隨機出現!

search: // ← 標籤
int y = 0;
while (y < H) {
    int x = 0;
    while (x < W) {
        if (cave[y][x] == 1) {
            System.out.println("發現! (" + y + "," + x + ")");
            break search; // 整個雙重迴圈退出!
        }
        x++;
    }
    y++;
}
System.out.println("探索結束");

如果寫成 continue search;,可以跳至外層的下一輪


🧪 continue 的使用時機(while 版)

  • 提早過濾不需要的數據“提前跳過”
    int i = 0;
    while (i < party.size()) {
    String name = party.get(i);
    if (name == null || name.isBlank()) { i++; continue; } // 跳過無名
    System.out.println(name + " 成為了首位!");
    i++;
    }
  • 減少遊戲日誌中的噪聲
    int j = 0;
    while (j < events.size()) {
    Event e = events.get(j);
    if (e.type() == Event.Type.DEBUG) { j++; continue; } // 不顯示調試行
    log(e);
    j++;
    }

🪄 下一次預告

下一次將探討 在實務中的 while 應用。包括輸入驗證/JDBC 的逐步獲取/狀態等待,
以及本次技巧應該如何應用!

皮卡丘!!


後記

謝謝你閱讀到這裡。
即使之前覺得「程式設計很難…」,如果能讓你覺得「可能有點有趣…!」我會很高興。
期待你的下次來訪!


💬 歡迎評論和反饋!

「這一章很容易理解!」
「這裡的表達沒有錯嗎?」
「希望下次可以做○○!」等等,
隨時歡迎留言告訴我!


原文出處:https://qiita.com/hitomin_poke/items/ad954cb433f21d425a70


共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
站長阿川

站長阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

站長精心設計,帶你實作 63 個小專案,得到作品集!

立即開始免費試讀!