2011-06-14 95 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 
     } 
    }); 
}