Java 的選擇語句(轉)

ba發表於2007-08-15
Java 的選擇語句(轉)[@more@]程式語言使用控制(control )語句來產生執行流,從而完成程式狀態的改變,如程式順序執行和分支執行。Java 的程式控制語句分為以下幾類:選擇,重複和跳轉。根據表示式結果或變數狀態選擇(Selection )語句來使你的程式選擇不同的執行路徑。重複(Iteration)語句使程式能夠重複執行一個或一個以上語句(也就是說,重複語句形成迴圈)。跳轉(Jump )語句允許你的程式以非線性的方式執行。下面將分析Java 的所有控制語句。

如果你熟悉C/C++ ,那麼掌握Java 的控制語句將很容易。事實上,Java 的控制語句與C/C++ 中的語句幾乎完全相同。當然它們還是有一些差別的——尤其是break語句與continue 語句。
Java 支援兩種選擇語句:if語句和switch語句。這些語句允許你只有在程式執行時才能知道其狀態的情況下,控制程式的執行過程。如果你沒有C/C++ 的程式設計背景,你將會為這兩個語句的強大功能和靈活性而感到吃驚。

5.1.1 if語句
if語句曾在第2章中介紹過,我們將在這裡對它進行詳細討論。if語句是Java 中的條件分支語句。它能將程式的執行路徑分為兩條。if語句的完整格式如下:

if (condition) statement1;
else statement2;

其中,if和else的物件都是單個語句(statement ),也可以是程式塊。條件condition 可以是任何返回布林值的表示式。else子句是可選的。

if語句的執行過程如下:如果條件為真,就執行if的物件(statement1 );否則,執行else 的物件(statement2 )。任何時候兩條語句都不可能同時執行。考慮下面的例子:

int a,b; // ...if(a < b) a = 0;else b = 0;

本例中,如果a小於b,那麼a被賦值為0;否則,b被賦值為0。任何情況下都不可能使a 和b都被賦值為0。

通常,用於控制if語句的表示式都包含關係運算子。當然,這在技術上並不是必要的。僅用一個布林值來控制if語句也是可以的,如下面的程式段:

boolean dataAvailable;
// ...
if (dataAvailable)
ProcessData();
else
waitForMoreData();

記住,直接跟在if 或else語句後的語句只能有一句。如果你想包含更多的語句,你需要建一個程式塊,如下面的例子:

int bytesAvailable;
// ...
if (bytesAvailable > 0) {

ProcessData();bytesAvailable -= n;} elsewaitForMoreData();

這裡,如果變數bytesAvailable 大於0,則if塊內的所有語句都會執行。

一些程式設計師覺得在使用if語句時在其後跟一個大括號是很方便的,甚至在只有一條語句的時侯也使用大括號。這使得在日後新增別的語句變得容易,並且你也不必擔心忘記括號。事實上,當需要定義塊時而未對其進行定義是一個導致錯誤的普遍原因。例如,考慮下面的程式段:

int bytesAvailable;
// ...
if (bytesAvailable > 0) {

ProcessData();bytesAvailable -= n;

} else
waitForMoreData();
bytesAvailable = n;

由於編排的原因,看起來似乎bytesAvailable = n 語句應該在else子句中執行。然而,當你呼叫時,空白對Java 無關緊要,編譯器無法知道你的意圖。這段程式會透過編譯,但運用時會出錯。上述例子應修改如下:

int bytesAvailable;
// ...
if (bytesAvailable > 0) {

ProcessData();
bytesAvailable -= n;

} else {
waitForMoreData();
bytesAvailable = n;

}

巢狀if 語句

巢狀(nested)if語句是指該if語句為另一個if或者else 語句的物件。在程式設計時經常要用到巢狀if語句。當你使用巢狀if語句時,需記住的要點就是:一個else語句總是對應著和它在同一個塊中的最近的if語句,而且該if語句沒有與其他else語句相關聯。下面是一個例子:
if(i == 10) {if(j < 20) a = b;if(k > 100) c = d; // this if iselse a = c; // associated with this else

}
else a = d; // this else refers to if(i == 10)

如註釋所示,最後一個else語句沒有與if(j <20 )相對應,因為它們不在同一個塊(儘管if(j <20 )語句是沒有與else配對最近的if語句)。最後一個else語句對應著if(i==10 )。內部的else語句對應著if(k>100 ),因為它是同一個塊中最近的if語句。

if-else-if 階梯

基於巢狀if語句的通用程式設計結構被稱為 if-else-if 階梯。它的語法如下:

if(condition) statement; else if(condition) statement; else if(condition)

statement;
.
.
.
else

statement;

條件表示式從上到下被求值。一旦找到為真的條件,就執行與它關聯的語句,該階梯的其他部分就被忽略了。如果所有的條件都不為真,則執行最後的else語句。最後的else語句經常被作為預設的條件,即如果所有其他條件測試失敗,就執行最後的else語句。如果沒有最後的else語句,而且所有其他的條件都失敗,那程式就不做任何動作。

下面的程式透過使用if-else-if 階梯來確定某個月是什麼季節。

// Demonstrate if-else-if statements.
class IfElse {

public static void main(String args[]) {
int month = 4; // April
String season;

if(month == 12 || month == 1 || month == 2)
season = "Winter";
else if(month == 3 || month == 4 || month == 5)
season = "Spring";
else if(month == 6 || month == 7 || month == 8)
season = "Summer";
else if(month == 9 || month == 10 || month == 11)
season = "Autumn";
else
season = "Bogus Month";

System.out.println("April is in the " + season + ".");
}
}
該程式產生如下輸出:

April is in the Spring.

在往下繼續講之前,你可能想要先試驗這個程式。你將看到,不管你給month 什麼值,該階梯中有而且只有一個語句執行。

5.1.2 switch 語句
switch語句是Java 的多路分支語句。它提供了一種基於一個表示式的值來使程式執行不同部分的簡單方法。因此,它提供了一個比一系列if-else-if 語句更好的選擇。switch 語句的通用形式如下:

switch (expression) {

case value1:

// statement sequence

break;

case value2:

// statement sequence

break;

.

.

.

case valueN:

// statement sequence

break;

default:

// default statement sequence

}

表示式expression 必須為byte,short,int 或char型別。每個case語句後的值value 必須是與表示式型別相容的特定的一個常量(它必須為一個常量,而不是變數)。重複的case值是不允許的。

switch 語句的執行過程如下:表示式的值與每個case語句中的常量作比較。如果發現了一個與之相匹配的,則執行該case語句後的程式碼。如果沒有一個case常量與表示式的值相匹配,則執行default 語句。當然,default 語句是可選的。如果沒有相匹配的case 語句,也沒有default 語句,則什麼也不執行。

在case語句序列中的break 語句將引起程式流從整個switch 語句退出。當遇到一個break 語句時,程式將從整個switch 語句後的第一行程式碼開始繼續執行。這有一種“跳出” switch 語句的效果。

下面是一個使用switch語句的簡單例子:

// A simple example of the switch.

class SampleSwitch {

public static void main(String args[]) {

for(int i=0; i<6; i++)

switch(i) {

case 0:

System.out.println("i is zero.");

break;
case 1:
System.out.println("i is one.");
break;

case 2:
System.out.println("i is two.");
break;

case 3:
System.out.println("i is three.");
break;

default:
System.out.println("i is greater than 3.");
}
}
}

該程式的輸出如下:

i is zero.
i is one.
i is two.
i is three.
i is greater than 3.
i is greater than 3.

從中可以看出,每一次迴圈,與i值相配的case常量後的相關語句就被執行。其他語句則被忽略。當i大於3時,沒有可以匹配的case語句,因此執行 default 語句。break語句是可選的。如果你省略了break 語句,程式將繼續執行下一個case語句。有時需要在多個case語句之間沒有break 語句。例如下面的程式:

// In a switch, break statements are optional.
class MissingBreak {
public static void main(String args[]) {
for(int i=0; i<12; i++)

switch(i) {
case 0:
case 1:
case 2:
case 3:
case 4:

System.out.println("i is less than 5");

break;
case 5:
case 6:
case 7:
case 8:
case 9:

System.out.println("i is less than 10");
break;
default:
System.out.println("i is 10 or more");
}
}
}
該程式產生的輸出如下:

i is less than 5
i is less than 5
i is less than 5
i is less than 5
i is less than 5
i is less than 10
i is less than 10
i is less than 10
i is less than 10
i is less than 10
i is 10 or more
i is 10 or more

正如該程式所演示的那樣,如果沒有break語句,程式將繼續執行下面的每一個case語

句,直到遇到break 語句(或switch語句的末尾)。當然該例子是為了示例而人為構造的,省略break語句在真實的程式中有許多實際的應

用。為了說明它更現實的用法,讓我們考慮下例對以前顯示季節例子的重寫。這個重寫的

版本使用switch語句來使程式的執行更高效。

// An improved version of the season program.
class Switch {

public static void main(String args[]) {
int month = 4;
String season;
switch (month) {

case 12:
case 1:
case 2:

season = "Winter";

break;
case 3:
case 4:
case 5:

season = "Spring";

break;
case 6:
case 7:
case 8:

season = "Summer";

break;
case 9:
case 10:
case 11:

season = "Autumn";
break;
default:

season = "Bogus Month";}System.out.println("April is in the " + season + ".");

}
}
巢狀switch 語句

可以將一個switch語句作為一個外部switch語句的語句序列的一部分,這稱為巢狀switch語句。因為一個switch語句定義了自己的塊,外部switch語句和內部switch語句的case 常量不會產生衝突。例如,下面的程式段是完全正確的:

switch(count) {

case 1:

switch(target) { // nested switch

case 0:

System.out.println("target is zero");

break;

case 1: // no conflicts with outer switch

System.out.println("target is one");

break; }

break;

case 2: // ...

本例中,內部switch語句中的 case 1 :語句與外部switch語句中的case 1:語句不衝突。變數count僅與外層的case語句相比較。如果變數count 為1,則變數target 與內層的case語句相比較。

概括起來說,switch語句有3個重要的特性需注意:

·
switch語句不同於if語句的是switch語句僅能測試相等的情況,而if語句可計算任何型別的布林表示式。也就是switch語句只能尋找case常量間某個值與表示式的值相匹配。
·
在同一個switch語句中沒有兩個相同的case常量。當然,外部switch語句中的case常量可以和內部switch語句中的case常量相同。
·
switch語句通常比一系列巢狀if語句更有效。
最後一點尤其有趣,因為它使我們知道Java 編譯器如何工作。當編譯一個switch語句時,Java 編譯器將檢查每個case常量並且創造一個“跳轉表”,這個表將用來在表示式值的基礎上選擇執行路徑。因此,如果你需要在一組值中做出選擇,switch 語句將比與之等效的if-else 語句快得多。編譯器可以這樣做是因為它知道case常量都是同型別的,所要做的只是將它與switch表示式相比較看是否相等。對於一系列的if表示式,編譯器就無此功能。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-958084/,如需轉載,請註明出處,否則將追究法律責任。

相關文章