2017-04-04 75 views
13

這是我的代碼:在陰影方面,for each和traditional for for循環之間有什麼區別?

class HelloWorld { 

    char[] foo = {'a', 'b'}; 

    // This will compile 
    void foo() { 
     for (char foo : foo) { 
     } 
    } 

    // This will not compile 
    void bar() { 
     for (char foo = 0; foo < foo.length; foo++) { 
     } 
    } 
} 

爲什麼foo編譯但編譯bar失敗:

Error: char cannot be dereferenced 

是什麼使循環foo中編譯,但酒吧兩個環路聲明之間的區別失敗?

+1

你是邏輯上操作/比較字符和整數之間的[<] - >怎麼可能不是eorneuos –

+0

你是否在字符類型中使用++?如果你使用相同的名字foo作爲ireration變量而不是數組變量,這個數組變量必須是錯誤 –

+2

爲什麼'bar'使用'char'變量?它不應該是一個'int'嗎?如果使用「int」,它仍然表現出相同的行爲嗎? – jpmc26

回答

15

我們可以通過處理數組時考慮如何增強for作品JLS§14.14.2的描述看出區別:

增強的for語句等價於一個基本的申請表格的聲明:

T[] #a = Expression; 
L1: L2: ... Lm: 
for (int #i = 0; #i < #a.length; #i++) { 
    {VariableModifier} TargetType Identifier = #a[#i]; 
    Statement 
} 

注意如何變量是體的循環,循環的不頭的內聲明。也就是說,你的foo功能是這樣的:

void foo() { 
    { // Freestanding block for scope, though not really needed as `foo` has 
     // nothing else in it 
     char[] a = foo;  // T[] #a = Expression; 
     for (int i = 0; i < a.length; i++) { 
      char foo = a[i]; // {VariableModifier} TargetType Identifier = #a[#i]; 
     } 
    } 
} 

這就是爲什麼你得逞的增強for的陰影,而不是在傳統的for,需要訪問原始陣列(以獲得其length,獲得i的條目等)。

更多關於增強for迴路How does the Java 'for each' loop work?及其答案。

8

Java語言規範定義了你的兩個char foo的的範圍不同:

在基本 for聲明ForInit部分聲明的局部變量的作用域(§14.14.1)包括所有的以下內容:

  • 它自己的初始化
  • 任何進一步的說明符到右邊的ForInit的for聲明
  • 表達ForUpdate部分for聲明
  • 所包含的聲明

中的FormalParameter部分聲明的局部變量的作用域的一部分 增強的for聲明(§14.14.2)是包含聲明。

JLS 8, section 6.3

,完美解釋了你觀察到的行爲:當地foo在基本for環路(無處不在其聲明中的右側)的控制條款的範圍,因此陰影其他foo,但在增強的for循環中,其作用域僅爲循環語句 - 它不在循環控制子句中的任何位置。