增強 for 循環(for-each 循環)是 J2SE 1.5 最受歡迎的語法糖之一。本文將揭示其編譯期轉換機制,並探討為何 Java 選擇 for 與 : 而非 foreach 與 in 關鍵字。
增強 for 循環在編譯期間會被轉換為傳統的索引遍歷或迭代器遍歷,因此不會產生任何執行期效能損耗。
原始寫法:
int[] integers = {1, 2, 3, 4};
for (int i : integers) {
System.out.println(i);
}
編譯器轉換後等價於:
int[] integers = {1, 2, 3, 4};
for (int idx = 0; idx < integers.length; idx++) {
int i = integers[idx];
System.out.println(i);
}
其中 idx 為編譯器自動生成的不會衝突的變數名。
原始寫法:
String[] strings = {"A", "B", "C", "D"};
Collection list = java.util.Arrays.asList(strings);
for (Object str : list) {
System.out.println(str);
}
編譯器轉換後等價於:
String[] strings = {"A", "B", "C", "D"};
Collection list = java.util.Arrays.asList(strings);
for (Iterator it = list.iterator(); it.hasNext(); ) {
Object str = it.next();
System.out.println(str);
}
同樣,it 為編譯器自動生成的迭代器變數名。
Java 採用 for 而非 foreach,使用 : 而非 in,主要為了**避免引入新關鍵字導致相容性問題**。
foreach 雖較少用作變數名,但 in 極常用於表示輸入流(如 System.in)。in 作為識別符的程式碼將無法編譯。雖然可透過上下文敏感語法設計讓關鍵字在特定場合才具特殊含義,但這會增加語法複雜度,未獲廣泛採用。Java 選擇復用現有 for 關鍵字,以冒號分隔,兼顧可讀性與向後相容。
由於編譯器將增強 for 循環轉換為標準遍歷形式,其執行效能與手寫傳統循環完全一致,開發者可放心使用,專注於業務邏輯而非效能微調。