JAVA中Goto和continue、break實現Goto__JAVA

來源:互聯網
上載者:User
goto 關鍵字很早就在程式設計語言中出現。事實上,goto 是組合語言的程式控制結構的始祖:“若條件 A,
則跳到這裡;否則跳到那裡”。若閱讀由幾乎所有編譯器產生的彙編代碼,就會發現程式控制裡包含了許多
跳轉。然而,goto 是在源碼的層級跳轉的,所以招致了不好的聲譽。若程式總是從一個地方跳到另一個地
方,還有什麼辦法能識別代碼的流程呢。隨著 Edsger Dijkstra 著名的“Goto 有害”論的問世,goto 便從此
失寵。
事實上,真正的問題並不在於使用 goto ,而在於 goto 的濫用。而且在一些少見的情況下,goto 是組織控制
流程的最佳手段。
儘管 goto 仍是 Java 的一個保留字,但並未在語言中得到正式使用;Java 沒有 goto 。然而,在 break 和
continue 這兩個關鍵字的身上,我們仍然能看出一些 goto 的影子。它並不屬於一次跳轉,而是中斷迴圈語
句的一種方法。之所以把它們納入 goto 問題中一起討論,是由於它們使用了相同的機制:標籤。
“標籤”是後面跟一個冒號的標識符,就象下面這樣:
label1:
對 Java 來說,唯一用到標籤的地方是在迴圈語句之前。進一步說,它實際需要緊靠在迴圈語句的前方——在
標籤和迴圈之間置入任何語句都是不明智的。而在迴圈之前設定標籤的唯一理由是:我們希望在其中嵌套另
一個迴圈或者一個開關。這是由於 break 和 continue 關鍵字通常只中斷當前迴圈,但若隨同標籤使用,它們
就會中斷到存在標籤的地方。如下所示:
label1:
外部迴圈{
內部迴圈{
//...
break; //1
//...
continue; //2
//...
continue label1; //3
//...
break label1; //4
}
}
在條件 1 中,break 中斷內部迴圈,並在外部迴圈結束。在條件 2 中,continue 移回內部迴圈的起始處。但
在條件 3 中,continue label1 卻同時中斷內部迴圈以及外部迴圈,並移至 label1 處。隨後,它實際是繼續
迴圈,但卻從外部迴圈開始。在條件 4 中,break label1 也會中斷所有迴圈,並回到 label1 處,但並不重
新進入迴圈。也就是說,它實際是完全中止了兩個迴圈。
下面是 for 迴圈的一個例子:

// : LabeledFor.java    // Java’s "labeled for loop"    public class LabeledFor {        public static void main(String[] args) {            int i = 0;            outer: // Can't have statements here            for (; true;) { // infinite loop                inner: // Can't have statements here                for (; i < 10; i++) {                    prt("i = " + i);                    if (i == 2) {                        prt("continue");                        continue;                    }                    if (i == 3) {                        prt("break");                        i++; // Otherwise i never                        // gets incremented.                        break;                    }                    if (i == 7) {                        prt("continue outer");                        i++; // Otherwise i never                        // gets incremented.                        continue outer;                    }                    if (i == 8) {                        prt("break outer");                        break outer;                    }                    for (int k = 0; k < 5; k++) {                        if (k == 3) {                            prt("continue inner");                            continue inner;                        }                    }                }            }            // Can't break or continue            // to labels here        }        static void prt(String s) {            System.out.println(s);        }    } // /:~


這裡用到了在其他例子中已經定義的 prt()方法。
注意 break 會中斷 for 迴圈,而且在抵達 for 迴圈的末尾之前,遞增運算式不會執行。由於 break 跳過了遞
增運算式,所以遞增會在 i==3 的情況下直接執行。在 i==7 的情況下,continue outer 語句也會到達迴圈頂
部,而且也會跳過遞增,所以它也是直接遞增的。

下面是輸出結果:
i = 0
continue inner
i = 1
continue inner
i = 2
continue
i = 3
break
i = 4
continue inner
i = 5
continue inner
i = 6
continue inner
i = 7
continue outer
i = 8
break outer
如果沒有 break outer 語句,就沒有辦法在一個內部迴圈裡找到出外部迴圈的路徑。這是由於 break 本身只
能中斷最內層的迴圈(對於 continue 同樣如此)。
當然,若想在中斷迴圈的同時退出方法,簡單地用一個 return 即可。
下面這個例子向大家展示了帶標籤的 break 以及 continue 語句在 while 迴圈中的用法:
// : LabeledWhile.java    // Java's "labeled while" loop    public class LabeledWhile {        public static void main(String[] args) {            int i = 0;            outer: while (true) {                prt("Outer while loop");                while (true) {                    i++;                    prt("i = " + i);                    if (i == 1) {                        prt("continue");                        continue;                    }                    if (i == 3) {                        prt("continue outer");                        continue outer;                    }                    if (i == 5) {                        prt("break");                        break;                    }                    if (i == 7) {                        prt("break outer");                        break outer;                    }                }            }        }        static void prt(String s) {            System.out.println(s);        }    } // /:~


同樣的規則亦適用於 while:
(1) 簡單的一個 continue 會退回最內層迴圈的開頭(頂部),並繼續執行。
(2) 帶有標籤的 continue 會到達標籤的位置,並重新進入緊接在那個標籤後面的迴圈。
(3) break 會中斷當前迴圈,並移離當前標籤的末尾。
(4) 帶標籤的 break 會中斷當前迴圈,並移離由那個標籤指示的迴圈的末尾。
這個方法的輸出結果是一目瞭然的:
Outer while loop
i = 1
continue
i = 2
i = 3
continue outer
Outer while loop
i = 4
i = 5
break
Outer while loop
i = 6
i = 7
break outer
大家要記住的重點是:在 Java 裡唯一需要用到標籤的地方就是擁有嵌套迴圈,而且想中斷或繼續多個嵌套級
別的時候。
在 Dijkstra 的“Goto 有害”論中,他最反對的就是標籤,而非 goto 。隨著標籤在一個程式裡數量的增多,
他發現產生錯誤的機會也越來越多。標籤和 goto 使我們難於對程式作靜態分析。這是由於它們在程式的執行
流程中引入了許多“怪圈”。但幸運的是,Java 標籤不會造成這方面的問題,因為它們的活動場所已被限
死,不可通過特別的方式到處傳遞程式的控制權。由此也引出了一個有趣的問題:通過限制語句的能力,反

而能使一項語言特性更加有用。


摘自《java編程思想》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.