在匿名类中访问循环变量

时间:2016-10-27 03:24:44

标签: java anonymous-class

我得到的错误是在public void pressed内,除非i设置为int,否则无法访问变量final。但是,如果我将其设置为final,则i++会成为错误。我被卡住了,除非我可以从我的内联函数中访问i变量。这可能吗?

for (int i = 0; i < level.myItems.size(); i++) {
    itemsInInventory[i].setButtonListener(new UIButtonListener() {
        public void pressed(UIButton button, Sprites sprite) {
            itemsInInventory[i].performAction();;
        }
    });
}

2 个答案:

答案 0 :(得分:4)

您可以在循环中声明final局部变量:

for(int i = 0; i < level.myItems.size(); i++){
    final int j = i;
    itemsInInventory[i].setButtonListener(new UIButtonListener(){
        public void pressed(UIButton button, Sprites sprite){
            itemsInInventory[j].performAction();
        }
    });
}

或者更好,因为您只需要按钮,而不是i

for(int i = 0; i < level.myItems.size(); i++){
    final UIButton btn = itemsInInventory[i];
    btn.setButtonListener(new UIButtonListener(){
        public void pressed(UIButton button, Sprites sprite){
            btn.performAction();
        }
    });
}

甚至更好(因为可能是pressed的第一个参数是按钮本身):

for(int i = 0; i < level.myItems.size(); i++){
    itemsInInventory[i].setButtonListener(new UIButtonListener(){
        public void pressed(UIButton button, Sprites sprite){
            button.performAction();
        }
    });
}

请注意,对于最后一个版本,您不需要为每个按钮单独UIButtonListener。只需将它们全部设置为具有相同的侦听器,并且侦听器将自动调度到相应的按钮:

UIButtonListener listener = new UIButtonListener(){
    public void pressed(UIButton button, Sprites sprite){
        button.performAction();
    }
};
for(int i = 0; i < level.myItems.size(); i++){
    itemsInInventory[i].setButtonListener(listener);
}

答案 1 :(得分:1)

问题是你的变量的生命周期与for循环有关,但你创建的对象可以永久存在。为了做这样的事情,变量需要是最终的,因此编译器知道它可以在匿名类中创建它的隐藏副本。你可以这样做:

for(int i = 0; i < foo; i++) {
    final int index = i;
    ... anonymous class using "index"...
}

Java 8使这更简单,但仅适用于Android N和更新版本。