2011-06-14 84 views
4

我在這裏面對的一個愚蠢問題的種類...基本上我在For循環中,並在此循環中,我總是調用一個函數來製作一個按鈕。但在這個函數中,我想通過循環迭代器,因爲它正在改變區分按鈕。但是,然後它告訴我我需要使循環迭代器「最終」,這意味着它不會改變!Java - 獲取循環迭代器到循環內的函數?

那麼我的問題會更有意義一些骨架代碼:

for(int i = 0; i < appList.size(); i++) { 

       //some other stuff including creating the below button 'btn' 

       btn.setOnClickListener(new View.OnClickListener() { 
        public void onClick(View v) { 
         //set some attribute based on i 
         //but when I do this it only sets based on the greatest value of i (!) 
        } 
       }); 
} 

咩有點傻問題,我知道...我是新來的Java,但!

乾杯。

+0

的評論說,你將設置基於i *使用的最大價值我*似乎不準確的屬性。由於答案中缺少關鍵字'final',因此您無法編譯包含代碼段的代碼。不過,您可能已經將整數包裝在最終的單個元素數組中,並且會得到您描述的行爲。 – Atreys 2011-06-14 15:37:04

回答

4
for(int i = 0; i < appList.size(); i++) { 

    final int _i = i; 

    btn.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      // use _i instead of i 
     } 
    }); 
} 
+1

'_i'必須宣佈'最終' – 2011-06-14 14:55:56

+0

是的,這是整點:) – 2011-06-14 15:02:50

+0

擊敗我,它應得的upvote ;-) – 2011-06-14 15:03:30

1

考慮該位的傻示例代碼:當i改變

int i = 0; 
obj.invokeThunkAfter10Seconds(new ThunkObject() { 
    public void thunk() { 
     System.out.println(i); 
    } 
} 
i = 1; 

ThunkObject保持到i的引用,但i可以改變,這使得輸出不可預測的,並取決於當thunk被調用。

由於Java沒有正確的關閉(按設計,請參閱Cannot refer to a non-final variable inside an inner class defined in a different method),因此您顯然不允許捕獲像這樣的非最終(即可變長)變量。

相反,您必須聲明變量final,這意味着它已初始化並且不可變更。這意味着你在內部課程被捕獲後永遠不能改變i

final int i = 0; 
obj.invokeThunkAfter10Seconds(new ThunkObject() { 
    public void thunk() { 
     System.out.println(i); 
    } 
} 
// Can't change i here. It will forever now be 0. 

在你的榜樣,你不能只是設置i是最後的,因爲你想更改每個循環迭代的值。相反,你可以在最後的變量創建值的副本:

for(int i = 0; i < appList.size(); i++) { 
    //some other stuff including creating the below button 'btn' 

    final int capturedI = i; 
    btn.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      //set some attribute based on capturedI 
     } 
    }); 
}