1. 程式人生 > >java 跳轉語句

java 跳轉語句

Java 支援 3 種跳轉語句:break,continue 和return 。這些語句把控制轉移到程式的其他部分。下面對每一種語句進行討論。

注意:除了這裡討論的跳轉語句,Java 還支援另一種能改變你程式執行流程的方法:通過異常處理。異常處理提供了一種結構化的方法,通過該方法可以使你的程式捕獲並處理執行時刻錯誤。它由下列五個關鍵字來控制:try,catch,throw,throws,和 finally 。實質上,異常處理機制允許你的程式完成一個非區域性的分支跳轉。由於異常處理是一個大話題,我們將專門討論。

5.3.1 使用break 語句
在Java 中,break語句有3種作用。第一,你已經看到,在switch語句中,它被用來終止一個語句序列。第二,它能被用來退出一個迴圈。第三,它能作為一種“先進”的goto 語句來使用。下面對最後 2種用法進行解釋。

使用break 退出迴圈

可以使用break 語句直接強行退出迴圈,忽略迴圈體中的任何其他語句和迴圈的條件測試。在迴圈中遇到break語句時,迴圈被終止,程式控制在迴圈後面的語句重新開始。下面是一個簡單的例子:

// Using break to exit a loop. 
class BreakLoop { 
    public static void main(String args[]) { 
        for(int i=0; i<100; i++) { 
            if(i == 10) break; // terminate loop if i is 10 
System.out.println("i: " + i); } System.out.println("Loop complete."); } }

該程式產生如下的輸出:

i: 0
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
Loop complete.

正如你看到的那樣,儘管for 迴圈被設計為從 0執行到99,但是當i等於10時,break語句終止了程式。break語句能用於任何 Java 迴圈中,包括人們有意設定的無限迴圈。例如,將上一個程式用while 迴圈改寫如下。該程式的輸出和剛才看到的輸出一樣。

// Using break to exit a while loop. 
class BreakLoop2 { 
    public static void main(String args[]) { 
    int i = 0; 
        while(i < 100) { 
            if(i == 10) break; // terminate loop if i is 10 
            System.out.println("i: " + i); 
            i++; 
        } 
    System.out.println("Loop complete."); 
    } 
} 

在一系列巢狀迴圈中使用break 語句時,它將僅僅終止最裡面的迴圈。例如:

// Using break with nested loops. 
class BreakLoop3 { 
public static void main(String args[]) { 
    for(int i=0; i<3; i++) { 
        System.out.print("Pass " + i + ":"); 
        for(int j=0; j<100; j++) { 
            if(j == 10) break; // terminate loop if j is 10
            System.out.print(j + " "); 
        } 
        System.out.println();
    } 
    System.out.println("Loops complete."); 
} 
} 

該程式產生如下的輸出:

Pass 0: 0 1 2 3 4 5 6 7 8 9
Pass 1: 0 1 2 3 4 5 6 7 8 9
Pass 2: 0 1 2 3 4 5 6 7 8 9
Loops complete.

從中可以看出,在內部迴圈中的break語句僅僅終止了該迴圈,外部的迴圈不受影響。

關於break ,在這裡要記住兩點。首先,一個迴圈中可以有一個以上的break 語句。但要小心,太多的break 語句會破壞你的程式碼結構。其次,switch語句中的break僅僅影響該switch 語句,而不會影響其中的任何迴圈。

注意:break 不是被設計來提供一種正常的迴圈終止的方法。迴圈的條件語句是專門用來終止迴圈的。只有在某類特殊的情況下,才用break 語句來取消一個迴圈。

把break 當作goto 的一種形式來用

break 語句除了在switch語句和迴圈中使用之外,它還能作為goto 語句的一種“文明”形式來使用。Java 中沒有 goto 語句,因為goto 語句提供了一種改變程式執行流程的非結構化方式。這通常使程式難以理解和難於維護。它也阻止了某些編譯器的優化。但是,有些地方goto 語句對於構造流程控制是有用的而且是合法的。例如,從巢狀很深的迴圈中退出時, goto 語句就很有幫助。因此,Java 定義了break 語句的一種擴充套件形式來處理這種情況。通過使用這種形式的break,你可以終止一個或者幾個程式碼塊。這些程式碼塊不必是一個迴圈或一個switch語句的一部分,它們可以是任何的塊。而且,由於這種形式的break 語句帶有標籤,你可以明確指定執行從何處重新開始。你將看到,break帶給你的是goto 的益處,並捨棄了goto 語句帶來的麻煩。

標籤break 語句的通用格式如下所示:

breaklabel;
這裡,標籤label 是標識程式碼塊的標籤。當這種形式的break執行時,控制被傳遞出指定的程式碼塊。被加標籤的程式碼塊必須包圍break 語句,但是它不需要是直接的包圍break的塊。這意味著你可以使用一個加標籤的break 語句退出一系列的巢狀塊。但是你不能使用break 語句將控制傳遞到不包含break 語句的程式碼塊。

要指定一個程式碼塊,在其開頭加一個標籤即可。標籤(label )可以是任何合法有效的Java 識別符號後跟一個冒號。一旦你給一個塊加上標籤後,你就可以使用這個標籤作為break 語句的物件了。這樣做會使執行在加標籤的塊的結尾重新開始。例如,下面的程式示例了 3 個巢狀塊,每一個都有它自己的標籤。break語句使執行向前跳,調過了定義為標籤second 的程式碼塊結尾,跳過了2個println ( ) 語句。

// Using break as a civilized form of goto.
class Break {
    public static void main(String args[]) {
        boolean t = true;
        first: {
            second: {
                third: {
                    System.out.println("Before the break.");
                    if (t)
                        break second; 
                        // break out of second block
                    System.out.println("This won't execute");
                }

                System.out.println("This won'texecute");
            }
            System.out.println("This is after secondblock.");

        }
    }
}

執行該程式,產生如下的輸出:

Before the break.
This is after second block.

標籤break 語句的一個最普遍的用法是退出迴圈巢狀。例如,下面的程式中,外層的迴圈只執行了一次:

// Using break to exit from nested loops
class BreakLoop4 {
    public static void main(String args[]) {
        outer: for (int i = 0; i < 3; i++) {
            System.out.print("Pass " + i + ":");
            for (int j = 0; j < 100; j++) {
                if (j == 10)
                    break outer; // exit both loops
                System.out.print(j + " ");
            }
            System.out.println("This will notprint");
        }
        System.out.println("Loops complete.");
    }
}

該程式產生如下的輸出:

Pass 0: 0 1 2 3 4 5 6 7 8 9 Loops complete.

你可以看到,當內部迴圈退到外部迴圈時,兩個迴圈都被終止了。記住如果一個標籤不在包圍break的塊中定義,你就不能break 到該標籤。例如,下面的程式就是非法的,且不會被編譯:

// This program contains an error.
class BreakErr {
    public static void main(String args[]) {
        one: for (int i = 0; i < 3; i++) {
            System.out.print("Pass " + i + ":");
        }
        for (int j = 0; j < 100; j++) {
            if (j == 10)
                break one; // WRONG
            System.out.print(j + " ");
        }
    }
}

因為標籤為one的迴圈沒有包圍break 語句,所以不能將控制傳遞到該塊。

5.3.2 使用continue 語句
有時強迫一個迴圈提早反覆是有用的。也就是,你可能想要繼續執行迴圈,但是要忽略這次重複剩餘的迴圈體的語句。實際上,goto 只不過是跳過迴圈體,到達迴圈的尾部。continue 語句是break語句的補充。在while 和do while 迴圈中,continue 語句使控制直接轉移給控制迴圈的條件表示式,然後繼續迴圈過程。在for 迴圈中,迴圈的反覆表示式被求值,然後執行條件表示式,迴圈繼續執行。對於這3種迴圈,任何中間的程式碼將被旁路。

下例使用continue 語句,使每行列印2個數字:

// Demonstrate continue.
class Continue {
    public static void main(String args[]) {
        for (int i = 0; i < 10; i++) {
            System.out.print(i + " ");
            if (i % 2 == 0)
                continue;
            System.out.println("");
        }
    }
}

該程式使用%(模)運算子來檢驗變數i是否為偶數,如果是,迴圈繼續執行而不輸出一個新行。該程式的結果如下:

0 1
2 3
4 5
6 7
8 9

對於break語句,continue 可以指定一個標籤來說明繼續哪個包圍的迴圈。下面的例子運用continue 語句來列印0到9的三角形乘法表:

class ContinueLabel {

    ContinueLabel() {

        outer: for (int i = 0; i < 10; i++) {

            for (int j = 0; j < 10; j++) {

                if (j > i) {
                    System.out.println();
                    continue outer;
                }

                System.out.print(" " + (i * j));
            }
        }

        System.out.println();

    }

} 

在本例中的continue 語句終止了計數j的迴圈而繼續計數i的下一次迴圈反覆。該程式的輸出如下:

0
0 1
0 2 4
0 3 6 9
0 4 8 12 16
0 5 10 15 20 25
0 6 12 18 24 30 36
0 7 14 21 28 35 42 49
0 8 16 24 32 40 48 56 64
0 9 18 27 36 45 54 63 72 81

很好的利用continue 語句的情況很少,一個原因是Java 提供了一系列豐富的迴圈語句,可以適用於絕大多數應用程式。但是,對於那些需要提早反覆的特殊情形,continue 語句提供了一個結構化的方法來實現。

5.3.3 使用return語句
最後一個控制語句是return。return語句用來明確地從一個方法返回。也就是,return 語句使程式控制返回到呼叫它的方法。因此,將它分類為跳轉語句。這裡對其作簡要地介紹。

在一個方法的任何時間,return 語句可被用來使正在執行的分支程式返回到呼叫它的方法。下面的例子說明這一點。下例中,由於是Java 執行系統呼叫main() ,因此,return語句使程式執行返回到Java 執行系統。


// Demonstrate return.
class Return {
    public static void main(String args[]) {
        boolean t = true;
        System.out.println("Before thereturn.");
        if (t)
            return; // return to caller
        System.out.println("This won'texecute.");
    }
}

該程式的結果如下:

Before the return.

正如你看到的一樣,最後的println( ) 語句沒有被執行。一旦return語句被執行,程式控制傳遞到它的呼叫者。

最後一點:在上面的程式中,if(t)語句是必要的。沒有它,Java 編譯器將標記“執行不到的程式碼”(unreachable code )錯誤,因為編譯器知道最後的println ()語句將永遠不會被執行。為阻止這個錯誤,為了這個例子能夠執行,在這裡使用if語句來“矇騙”編譯器。