2014-02-17 121 views
1

具有最終的變量是如何考慮這一段代碼在foreach循環工作

public static void main(String[] args) { 
    for(final String s : Arrays.asList("a","b","c")){ 
     System.out.println(s); 
    } 
} 

此代碼不服務於特定的目的,但證明finalforeach-loop變量的使用。

這是如何工作的?單個變量如何可以是final,但是每個循環都有一個不同的值。或者這個變量在不同的作用域\堆棧中多次聲明?

+1

我想會這樣。如果編譯器沒有抱怨,暗示爲每次迭代的字符串分配一個新的內存地址。所以舊的變量每次迭代都會超出範圍。 –

+1

@GuyBouallet:這不是真的重複。這個問題是關於for-each循環的循環變量(而不是在循環體內聲明的任意變量)。 –

回答

3

這在Java語言規範(JLS),14.14.2解釋:

增強的for語句的形式:

EnhancedForStatement: 
    for (FormalParameter : Expression) Statement 

FormalParameter: 
    VariableModifiers_opt Type VariableDeclaratorId 

VariableDeclaratorId: 
    Identifier 
    VariableDeclaratorId [] 

...

增強的for語句相當於 的基本聲明形式:

for (I #i = Expression.iterator(); #i.hasNext();) { 
    VariableModifiers_opt TargetType Identifier = 
     (TargetType) #i.next(); 
    Statement 
} 

因此,Identifier在循環的每次迭代中重新聲明。

+0

這比我對'for-each'循環的想法還要糟糕。我猜舊式'for-loop'是更優化的。 –

+0

@MuhammadGelbana:我不確定我看到這是如何「未優化」的? –

+0

它需要更多的堆棧和循環次數一樣多,以便能夠多次聲明具有相同名稱的變量。使用舊循環時,我可以在循環外部聲明相同的引用並在循環內重新分配它。 –

0

它只是意味着你不能在對象引用被設置後修改它。所以在這種情況下,「最終」僅適用於每次迭代。 :D

1

允許在該上下文中使用final的主要思想是讓您在匿名類中使用循環變量。除此之外,final不會更改循環變量s的語義:它會像平常一樣通過集合中的元素。

使用final的另一個影響是您不再允許您爲s分配新值。這通常是一個壞主意,雖然the compiler lets you do it