前言
在 Java 中,程式不一定只能由上而下執行。透過控制結構(if、switch、迴圈),可以讓程式根據條件改變流程。
本文將介紹 Java 中幾種常見的控制結構,並透過簡單範例說明其基本用法。本文適合初學者快速掌握 Java 控制流程的基本寫法。
if 敘述
if 是最基本的選擇控制結構,只有在條件成立時,對應的程式碼區塊才會執行。
以下程式碼片段使用隨機數,並判斷該數值為奇數或偶數:
var max = 10;
var min = 1;
var random = new Random();
var n = random.nextInt(max - min + 1) + min;
if (n % 2 == 0) {
IO.println(n + " is even");
}
else {
IO.println(n + " is odd");
}
switch 敘述
switch 也是一種選擇控制結構,適用於「值的比對」,語法上比多重 if-else 更簡潔。
需要特別注意的是,case 結尾若忘記加上 break,程式會繼續往下執行下一個 case,這種現象稱為 fallthrough。有時這是刻意設計,但更多時候會變成 bug。
以下程式碼片段依照星期幾輸出對應的訊息:
var now = new Date();
var c = GregorianCalendar.getInstance();
c.setTime(now);
var dow = c.get(GregorianCalendar.DAY_OF_WEEK);
switch (dow) {
case Calendar.SATURDAY:
case Calendar.SUNDAY:
IO.println("Weekend");
break;
case Calendar.FRIDAY:
IO.println("Thanks God. It's Friday");
break;
case Calendar.WEDNESDAY:
IO.println("Hump day");
break;
default:
IO.println("Week");
break;
}
此範例中刻意使用了一次 fallthrough(Calendar.SATURDAY、Calendar.SUNDAY 共用邏輯),這是符合預期的設計,而非錯誤。
while 敘述
while 是基本的迴圈控制結構,只要條件成立,就會持續重複執行同一段程式碼。
var i = 1;
while (i <= 10) {
IO.println(i);
++i;
}
需要注意的是,如果結束條件設計不當,可能會導致無窮迴圈(infinite loop)。某些情況下這是刻意設計,但在多數情境中代表程式邏輯有誤。
for 敘述
使用計數器(Counter)
最常見的 for 迴圈形式,是使用計數器控制執行次數:
for (var i = 1; i <= 10; ++i) {
IO.println(i);
}
使用迭代器(Iterator)
另一種 for 迴圈用法需搭配集合(collection)或迭代器,這部分會在介紹容器時再進一步說明。
改變迴圈行進的敘述
break 敘述
break 可用來提早中斷迴圈:
for (var i = 1; i <= 10; ++i) {
if (i > 5)
break;
IO.println(i);
}
除了迴圈之外,switch 也依賴 break 來區隔各個 case。
continue 敘述
continue 用來跳過當前這一輪迴圈剩餘的程式碼,直接進入下一次迭代:
for (var i = 1; i <= 10; ++i) {
if (i % 2 != 0)
continue;
IO.println(i);
}
(選讀) 終極密碼(Da Vinci Code)
前面的範例多半較為簡短,不容易體會控制結構在實際程式中的運作方式。本節透過一個較完整的範例,觀察如何組合這些控制結構。
這是一個常見的猜數字遊戲,其執行過程如下:
$ java Main.java
Input a number (1, 100): 50
Too small
Input a number (50, 100): 75
Too big
Input a number (50, 75): 63
Too big
Input a number (50, 63): 57
Too big
Input a number (50, 57): 53
You guess right
建議先嘗試自行實作,再參考以下程式碼片段:
/* Set the initial range of a answer. */
var max = 100;
var min = 1;
/* Get a random answer
between `min` and `max`. */
var random = new Random();
var answer = random.nextInt(max - min + 1) + min;
while (true) {
/* Try to receive a valid input
from the user. */
int guess;
while (true) {
/* Prompt the user for an input. */
var input = System.console().readLine(
"Input a number "
+ "(" + min + ", "
+ max + "): ");
try {
/* Parse the input. */
guess = Integer.parseInt(input);
}
catch (Exception e) {
/* It fails to parse the input.
Skip to next iteration. */
IO.println("Invalid number: " + input);
continue;
}
/* The guess out of range.
Skip to next iteration. */
if (!(min <= guess && guess <= max)) {
IO.println("Number out of range: " + guess);
continue;
}
/* The guess is valid.
Exit the input loop. */
break;
}
if (guess < answer) {
IO.println("Too small");
min = guess;
}
else if (answer < guess) {
IO.println("Too big");
max = guess;
}
else {
IO.println("You guess right");
/* The guess is equal to the answer.
Exit the game loop. */
break;
}
}
此範例的核心是一個遊戲迴圈(game loop),可分為兩個部分:
- 取得並驗證使用者輸入
- 判斷猜測結果並更新範圍
由於程式無法預先保證使用者輸入正確,因此使用一個內層迴圈持續讀取輸入,直到取得合法數值為止。輸入錯誤時,透過 continue 直接進入下一輪。
當輸入合法後,再依照猜測結果更新上下限,或在猜中時使用 break 結束整個遊戲。
繼續深入
若想進一步練習,可以嘗試擴充此程式,例如:
- 由使用者決定數值範圍
- 限制猜測次數
- 加入分數機制(猜對加分、猜錯扣分)
這些延伸練習有助於熟悉控制結構在實務中的組合方式。