語句
| 導航 語言基礎 主題: |
現在我們已經將 Java 平臺安裝到了系統上,並且成功運行了第一個程式,接下來我們將瞭解程式是如何編寫的。正如我們之前討論的,程式是一組指令,即提供給計算機的任務。在 Java 中,這些指令被稱為 **語句**。語句可以是單行程式碼,也可以是複雜的數學方程式。考慮以下程式碼行
程式碼節 3.1:簡單的賦值語句。
int age = 24;
|
這行程式碼是一個簡單的指令,它告訴系統初始化一個變數並將其值設定為 24。如果上述語句是程式中唯一的語句,它將類似於下面這樣
程式碼列表 3.1:簡單類中的語句。
public class MyProgram
{
public static void main(String[] args)
{
int age = 24;
}
}
|
Java 將其語句放在類宣告中,在類宣告中,語句通常放在方法宣告中,如上所示。
最簡單的語句是變數宣告
程式碼節 3.2:簡單的宣告語句。
int age;
|
它定義了一個變數,該變數可以用來儲存值以供以後使用。第一個標記是變數的 資料型別(該變數可以儲存哪種型別的值)。第二個標記是變數的名稱,您將透過它來引用該變數。然後每個宣告語句都以分號 (;) 結尾。
到目前為止,我們一直假設變數的建立是一個單獨的語句。實質上,我們為這些變數分配一個值,這就是它的名稱。當您在語句中為變數分配一個值時,該語句被稱為 **賦值語句**(也稱為 初始化語句)。您是否注意到還有一件事?是分號 (;),它位於每個語句的末尾。明確表明一行程式碼是語句的標誌是它以分號結尾。如果要編寫多個語句,通常會將每個語句放在單獨一行,並以分號結尾。考慮以下示例
程式碼節 3.3:多個賦值語句。
int a = 10;
int b = 20;
int c = 30;
|
您不必一定要使用新行來編寫每個語句。就像英語一樣,您可以從結束第一個語句的地方開始編寫下一個語句,如下所示
程式碼節 3.4:同一行上的多個賦值語句。
int a = 10; int b = 20; int c = 30;
|
但是,將多個語句放在同一行中的唯一問題是,它非常難讀。起初它看起來並不那麼嚇人,但一旦您擁有大量的程式碼,通常最好以一種有意義的方式來組織它。如果按照程式碼列表 3.4 中的寫法,它看起來會更加複雜和難以理解。
現在我們已經瞭解了簡單的賦值語句的結構,我們可以回顧一下我們所取得的成就。我們知道...
- 語句是程式設計中程式碼的單位。
- 如果我們要為變數分配一個值,則該語句被稱為賦值語句。
- 賦值語句包括三個部分:資料型別、變數名(也稱為識別符號)和變數的值。我們將在後面的“變數”部分詳細介紹識別符號和值的性質。
現在,在我們繼續下一個主題之前,您需要嘗試理解以下程式碼的作用。
程式碼節 3.5:包含表示式的多個賦值語句。
int firstNumber = 10;
int secondNumber = 20;
int result = firstNumber + secondNumber;
System.out.println(result);
secondNumber = 30; // This won't change the value of secondNumber. See the note.
System.out.println(result); // Hence, the result will remain same.
|
前兩個語句與 節 3.3 中的語句非常相似,但變數名不同。但是,第三個語句有點意思。我們已經談到變數類似於禮品盒。將您的計算機記憶體想象成一個架子,您將所有這些盒子都放在上面。無論何時需要一個盒子(或變數),您都會呼叫它的識別符號(即變數的名稱)。因此,呼叫變數識別符號 firstNumber 會得到數字 10,呼叫 secondNumber 會得到 20,因此,將兩者相加,結果應該是 30。這就是最後一個變數 result 的值。第三個語句中將數字相加的部分,即 firstNumber + secondNumber,被稱為 **表示式**,表示式決定了值的取值。如果它只是一個簡單值,就像前兩個語句中的那樣,那麼它被稱為 **字面量**(值 **字面意思** 就是值,因此稱為 **字面量**)。
請注意,在為 result 賦值後,如果我們為 firstNumber 或 secondNumber 分配不同的值,如第 5 行所示,它的值不會改變。
有了您剛剛獲得的資訊,您實際上可以編寫一個可以將值加起來的不錯的 Java 程式。
斷言檢查條件是否為真
程式碼節 3.6:返回語句。
public int getAge()
{
assert age >= 0;
return age;
}
|
每個 assert 語句都以分號 (;) 結尾。但是,斷言預設情況下是停用的,因此您必須使用 -ea 引數執行程式才能啟用斷言 (java -ea [已編譯程式的名稱])。
語句按照其出現的順序進行求值。執行流從最上面的語句開始,向下進行,直到遇到最後一個語句。語句可以被語句塊替換。有一些特殊的語句可以根據條件重定向執行流,這些語句被稱為 **分支** 語句,將在後面的部分詳細介紹。
一組語句可以放在花括號中,作為單個塊執行。這樣的語句塊可以命名,也可以為執行提供條件。以下是將一系列語句放在塊中的方法。
程式碼節 3.7:語句塊。
{
int a = 10;
int b = 20;
int result = a + b;
}
|
可以使用函式/方法呼叫、迴圈和迭代來影響程式流。在各種型別的分支結構中,我們可以輕鬆地挑選出兩種通用的分支方法。
- 無條件分支
- 條件分支
如果仔細觀察一個方法,你會發現方法是一個命名語句塊,透過呼叫該特定名稱來執行。無條件分支是透過呼叫方法或呼叫break、continue、return或throw建立的,這些將在下面介紹。
當在流程中遇到另一個方法的名稱時,它會在當前方法中停止執行並分支到新呼叫的方法。從呼叫的方法返回一個值後,執行將從呼叫方法下面一行的原始方法恢復。
|
|
程式流程從main方法開始。就像呼叫aMethod一樣,流程會移動到被呼叫的方法。此時,流程分支到另一個方法。方法完成後,流程返回到它離開的位置,並在呼叫方法後的下一條語句處繼續。
返回語句
[edit | edit source]一個return語句退出一個塊,因此它通常是方法的最後一條語句。
程式碼部分 3.9:一個返回語句。
public int getAge() {
int age = 24;
return age;
}
|
返回語句可以返回一個變數的內容或什麼都不返回。注意不要在返回語句之後編寫不會被執行的語句!每個return語句都以分號 (;) 結尾。
條件分支語句
[edit | edit source]條件分支是藉助if...else和switch語句實現的。只有當某個條件表示式計算結果為 true 時,才會發生條件分支。
條件語句
[edit | edit source]也稱為if語句,它們允許程式執行測試,然後根據測試結果採取行動。
if語句的形式
if(condition) { do statements here if condition is true }else{ do statements here if condition is false }
條件是一個布林表示式,它可以是true或false。執行的操作將取決於條件的值。
示例
程式碼部分 3.10:一個 if 語句。
if (i > 0) {
System.out.println("value stored in i is greater than zero");
} else {
System.out.println("value stored is not greater than zero");
}
|
使用 else if 組合可以使 if 語句更復雜
if(condition 1) { do statements here if condition 1 is true }elseif(condition 2) { do statements here if condition 1 is false and condition 2 is true }else{ do statements here if neither condition 1 nor condition 2 is true }
示例
程式碼部分 3.11:一個 if/else if/else 語句。
if (i > 0) {
System.out.println("value stored in i is greater than zero");
} else if (i < 0) {
System.out.println("value stored in i is less than zero");
} else {
System.out.println("value stored is equal to 0");
}
|
如果在條件之後只有一條語句要執行,如上面的例子,可以省略花括號,但 Oracle 的 Java 程式碼約定 明確說明應始終使用花括號。
if 語句中沒有迴圈,因此一旦條件被評估,程式將繼續執行語句後的下一條指令。
If...else 語句
[edit | edit source]if ... else 語句用於根據布林條件的結果有條件地執行兩個語句塊中的一個。
示例
程式碼部分 3.12:一個 if/else 語句。
if (list == null) {
// This block of statements executes if the condition is true.
} else {
// This block of statements executes if the condition is false.
}
|
Oracle 的 Java 程式碼約定 建議始終使用花括號。
一個if語句有兩種形式
if (boolean-condition)
statement1
和
if(boolean-condition) statement1elsestatement2
如果需要在布林條件為 true 或 false 時執行不同的語句,則使用第二種形式。如果只想在條件為 true 時執行statement1,並且不想在條件為 false 時執行備用語句,則使用第一種形式。
程式碼部分 3.13呼叫兩個int方法,f()和y(),儲存結果,然後使用一個if語句來測試x是否小於y,如果是,則statement1主體將交換值。最終結果是 x 始終包含較大的結果,y 始終包含較小的結果。
程式碼部分 3.13:值交換。
int x = f();
int y = y();
if (x < y) {
int z = x;
x = y;
y = z;
}
|
if...else語句也允許使用另一個語句,else if。此語句用於為條件提供另一個if語句,該語句只有在其他語句不為 true 時才能執行。例如
程式碼部分 3.14:多路分支。
if (x == 2)
x = 4;
else if (x == 3)
x = 6;
else
x = -1;
|
else if語句在這種情況下很有用,因為如果其中一個條件為 true,則另一個條件必須為 false。請記住,如果一個為 true,則另一個不會執行。例如,如果第一條條件語句中第 2 行的語句更改為x = 3;,則第二個條件語句,else if,仍然不會執行。但是,在處理條件語句中的基本型別時,最好使用switch 語句,而不是多個else if語句。
switch 語句
[edit | edit source]switch條件語句基本上是編寫許多if...else語句的簡寫。switch語句的語法如下
switch(<variable>) {
case <result>: <statements>; break;
case <result>: <statements>; break;
default: <statements>; break;
}
這意味著,如果包含的變數等於 case 結果之一,則會執行該 case 之後直到 break 關鍵字之間的語句。如果其他 case 都為假,則執行 default case。注意:只有 switch 語句可以分析的型別是 char、byte、short 或 int 原生型別。這意味著 Object 變數不能透過 switch 語句進行分析。但是,從 JDK 7 版本開始,你可以在 switch 語句的表示式中使用 String 物件。
程式碼部分 3.15:一個 switch。
int n = 2, x;
switch (n) {
case 1: x = 2;
break;
case 2: x = 4;
break;
case 3: x = 6;
break;
case 4: x = 8;
break;
}
return x;
|
在這個例子中,由於整型變數 n 等於 2,所以 case 2 會執行,使 x 等於 4。因此,該方法返回 4。
迭代語句
[edit | edit source]迭代語句用於迭代語句塊。這些語句通常被稱為迴圈。Java 提供了四種迭代語句。
while迴圈do...while迴圈for迴圈foreach迴圈
while 迴圈
[edit | edit source]while 迴圈在它指定的條件為 true 時迭代程式碼塊。
迴圈的語法為
while (condition) {
statement;
}
這裡條件是一個表示式。如前所述,表示式是任何返回值的語句。while 條件語句評估為布林值,即 true 或 false。只要條件為 true,迴圈就會一遍又一遍地迭代程式碼塊。一旦條件評估為 false,迴圈就會退出到迴圈之外的下一條語句。
do...while 迴圈
[edit | edit source]do-while 迴圈在功能上類似於 while 迴圈,除了條件在語句執行之後評估。
do{ statement; }while(condition);
for 迴圈
[edit | edit source]for 迴圈是一個專門的 while 迴圈,其語法旨在輕鬆迭代數字序列。示例
|
|
程式列印了 0 到 99 的數字及其平方。
while 迴圈中的相同語句
程式碼部分 3.17:一個替代版本。
int i = 0;
while (i < 100) {
System.out.println(i + "\t" + i * i);
i++;
}
|
foreach 迴圈
[edit | edit source]foreach 語句允許你遍歷集合中的所有專案,依次檢查每個專案,同時保留其型別。foreach 語句的語法為
for (type item : collection) statement;
例如,我們將使用一個 String 陣列,表示一週中的幾天,並遍歷該集合,一次檢查一個專案。
|
|
請注意,迴圈在集合中的最後一個專案在語句塊中被檢查後會自動退出。
雖然增強的 for 迴圈可以使程式碼更清晰,但它不能在一些常見的情況下使用。
- 只讀訪問。元素不能被賦值,例如,不能遞增集合中的每個元素。
- 僅單個結構。不可能同時遍歷兩個結構,例如,比較兩個陣列。
- 僅單個元素。僅用於訪問單個元素,例如,不能比較相鄰的元素。
- 僅向前。只能以單個步長向前迭代。
- 至少是 Java 5。如果你需要與 Java 5 之前的版本相容,請不要使用它。
continue 和 break 語句
[edit | edit source]有時,你可能希望重新迭代迴圈,而不執行迴圈中剩餘的語句。 語句會導致迴圈重新迭代,並從迴圈中最頂部的語句開始。continue
如果有重新迭代迴圈的能力,那麼就存在退出迴圈的能力。在任何時候,如果你想退出迴圈並結束迴圈中的所有進一步操作,則應該使用 。break
和 continue 語句可以與標籤一起使用,如下所示break
程式碼部分 3.19:使用標籤。
String s = "A test string for the switch!\nLine two of test string...";
outer: for (int i = 0; i < s.length(); i++) {
switch (s.charAt(i)) {
case '\n': break outer;
case ' ': break;
default: System.out.print(s.charAt(i));
}
}
|
程式碼清單 3.19 的輸出
Ateststringfortheswitch! |
throw 語句
[edit | edit source]throw 語句會退出方法,等等,或者被 try/catch 塊捕獲。它不返回變數,而返回異常
程式碼部分 3.20:一個 return 語句。
public int getAge() {
throw new NullPointerException();
}
|
注意不要在 throw 語句之後編寫不會執行的語句!每個 throw 語句都以分號 (;) 結尾。
try/catch
[edit | edit source]try/catch 至少必須包含 try 塊和 catch 塊
程式碼部分 3.21:try/catch 塊。
try {
// Some code
} catch (Exception e) {
// Optional exception handling
} finally {
// This code is executed no matter what
}
|
問題 3.1:這個類中有多少個語句?
程式碼清單 3.2:AProgram.java
public class AProgram {
private int age = 24;
public static void main(String[] args) {
int daysInAYear = 365;int ageInDay = 100000;
int localAge = ageInDay / daysInAYear;
}
public int getAge() {
return age;
}
}
|
5
第 3 行有一個語句,第 6 行有兩個語句,第 7 行有一個語句,第 11 行有一個語句。